有没有办法将 Linuxwireguard 模块配置为仅侦听特定 IP 地址的传入连接,而不是默认侦听所有可用地址?我找不到这方面的任何文档。
答案1
WireGuard 的 Linux 内核模块无法选择接口用于隧道的 IP 地址。
特别是,遵循OP的评论如果希望它不与 IPv4 绑定而只与 IPv6 绑定,则它将始终使用 IPv4,如外部兼容模块或者上游模块:
int wg_socket_init(struct wg_device *wg, u16 port) {
struct socket *new4 = NULL, *new6 = NULL; struct udp_port_cfg port4 = { .family = AF_INET, .local_ip.s_addr = htonl(INADDR_ANY), .local_udp_port = htons(port), .use_udp_checksums = true }; #if IS_ENABLED(CONFIG_IPV6) int retries = 0; struct udp_port_cfg port6 = {
ret = udp_sock_create(net, &port4, &new4); if (ret < 0) { pr_err("%s: Could not create IPv4 socket\n", wg->dev->name); goto out; }
IPv4 套接字创建(以及 IPv6,如果可用)是强制性的,并且始终使用INADDR_ANY
.
代码可能需要进行多项修改才能解决问题的标题:
- 选择使用或禁用哪个协议,
- 选择要使用的地址而不是
INADDR_ANY
和IN6ADDR_ANY_INIT
/&in6addr_any
(可能与上一个项目符号交互), - 当然,改变代码的所有部分期望不同。
然后,为了与用例实现跨操作系统兼容性,还必须对 WireGuard 的用户空间变体和其他内核(例如 FreeBSD)变体执行此操作。
同时对于一些想要的用例:
允许 WireGuard 隧道信封仅在单个地址、单个接口或单个 IP 版本(例如仅 IPv6)上可达:
使用防火墙仅限制对此地址或接口或 IP 版本/系列的访问
允许多个不同的 WireGuard 接口在不同接口上使用同一端口
将它们设置在不同的端口上并使用 NAT 规则(通常在初始入口情况的预路由中使用 DNAT,在初始出口情况的后路由中使用 SNAT)以使可见端口与实际使用的端口匹配。
避免绑定主机上的UDP端口
将 WireGuard 隐藏在其自己的命名空间中,至少在其初始创建时隐藏,WireGuard 端口将保留在其中。然后添加额外的路由层(可能还加上 NAT 规则,但它几乎与绑定端口相同)以到达隧道信封(即:此 UDP 端口,无论它在哪里),如果留在其他名称空间中,则还需要其他用于隧道有效负载的附加路由层。