我有一台带有多个 WireGuard VPN 的服务器。
每个 VPN 都是独立于其他 VPN 的,它们之间没有连接。
某些 VPN 连接到具有相同地址空间的远程 LAN。例如,我的 OFFICE_1 和 OFFICE_2 均使用 192.168.0.0/24。
我使用 LXC 创建托管 WireGuard 的“虚拟机”,因此相同的远程 LAN 不是问题,因为每个 WireGuard 都位于单独的虚拟机上。
该方案虽然简单,但对于系统维护来说不太方便。
我不习惯其他方法。基于策略的路由、网络命名空间、cgroup 或其他什么是更好的选择?
答案1
使用 LXC 虚拟机(或容器)来实现这一点既方便又简单(尽管您可能需要对服务器上的防火墙进行一些修改才能将 WireGuard 监听端口转发到虚拟机/容器)。
但只要服务器在每个 WireGuard 网络中使用不同的地址(例如,对于192.168.0.1
OFFICE_1、192.168.0.2
OFFICE_2 等),您就可以为此使用策略路由。如果你使用快速工作组要启动服务器上的每个 WireGuard 接口,您可以PreUp
在服务器的 WireGuard 配置文件中添加必要的策略规则作为命令:
# /etc/wireguard/office1.conf
[Interface]
PrivateKey = 123ABC...
Address = 192.168.0.1/32
ListenPort = 51821
Table = 111
PreUp = ip rule add iif office1 table 111 priority 101
PostDown = ip rule del iif office1 table 111 priority 101
[Peer]
PublicKey = 123DEF...
AllowedIPs = 192.168.0.10/32
[Peer]
PublicKey = 123GHI...
AllowedIPs = 192.168.0.11/32
# /etc/wireguard/office2.conf
[Interface]
PrivateKey = 234ABC...
Address = 192.168.0.2/32
ListenPort = 51822
Table = 222
PreUp = ip rule add iif office2 table 222 priority 102
PostDown = ip rule del iif office2 table 222 priority 102
[Peer]
PublicKey = 234DEF...
AllowedIPs = 192.168.0.10/32
[Peer]
PublicKey = 234GHI...
AllowedIPs = 192.168.0.11/32
上述配置文件中的设置Table
告诉 wg-quick 在添加与每个对等点的设置相对应的路由时使用命名路由表AllowedIPs
。该PreUp
命令添加一条策略路由规则,以在路由来自匹配 WireGuard 接口的传入连接时使用该表(并且该PostDown
命令会删除该规则)。
如果服务器需要启动与某个 WireGuard 网络中另一台主机的连接,则需要显式使用该 WireGuard 网络中的接口或地址来触发正确的策略规则;例如,要 ping 上述office1
网络中的主机,您需要指定该网络中服务器的 WireGuard 地址 ( 192.168.0.1
):
ping -I 192.168.0.1 192.168.0.10
另外,您需要确保服务器上的防火墙允许在每个 WireGuard 网络中的主机之间转发连接(例如,iptables -A FORWARD -i office1 -o office1 -j ACCEPT
如果您想允许在office1
主机之间不受限制地转发)。
但是,如果服务器需要为每个 WireGuard 网络使用相同的地址(例如,192.168.0.1
对于 OFFICE_1 以及192.168.0.1
OFFICE_2 等),那么您无法避免使用某种形式的容器化。最轻量级的版本只是为每个 WireGuard 接口创建一个单独的网络命名空间。
的“普通容器化”部分WireGuard 路由和网络命名空间集成指南通过一个巧妙的技巧演示了这一点,避免了在服务器上进行任何端口转发(通过在根命名空间中创建每个 WireGuard 接口,然后将其移动到自定义命名空间中)。
使用网络命名空间(而不是完整容器)的缺点是您无法使用 wg-quick 来帮助您 - 您必须手动运行 wg-quick 通常会运行的一些 iproute2 命令来设置WireGuard 接口。