我需要在同一台客户端计算机上配置 2 个不同的wireguard VPN 网络并将它们嵌套,这样当我发出请求时,它会通过 VPN_1,然后通过 VPN_2,然后到达目标网站。这里描述了类似的东西: https ://mullvad.net/en/help/different-entryexit-node-using-wireguard-and-socks5-proxy/
目前,当在主机上配置 VPN_1,在 docker 容器中配置 VPN_2 并通过 socks 代理公开时,我有一个工作配置。如果我将我的应用程序配置为使用 socks5 代理,它就可以完成工作,并且我有 APP -> VPN_1 -> VPN_2 -> 目的地。我想在单个 docker 容器中实现相同的目标(最好没有任何 socks 代理)。
我的第一个想法是使用相同的接口和 2 个对等点(并通过 AllowedIPs 参数配置路由,以便 VPN_1 使用 0.0.0.0/0 和 VPN_2 使用 <VPN_1 IP>/32)但我有 2 个不同的私钥所以可能不会去工作。我也尝试有 2 个单独的接口,但这也不起作用。
示例配置(最新):VPN_1
[Interface]
PrivateKey = <PRIVATE_KEY_1>
Address = 10.68.187.50/32
MTU = 1280
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o wg2 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o wg2 -j MASQUERADE
[Peer]
PublicKey = <PUBLIC_KEY_1>
AllowedIPs = 0.0.0.0/0
Endpoint = <VPN_1>:51820
PersistentKeepalive = 120
VPN_2
[Interface]
PrivateKey = <PRIVATE_KEY_2>
Address = 172.16.0.2/32
MTU = 1280
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = <PUBLIC_kEY_2>
AllowedIPs = <VPN_1_IP>/32
Endpoint = <VPN_2>
PersistentKeepalive = 120
我还发现一些 WireGuard 客户端具有开箱即用的此功能: https ://www.wiresock.net/ (双 VPN(带有嵌套隧道))。
但是使用 docker 设置,我现在有点卡住了,不胜感激。
UPDwg-quick
输出:
/ # wg-quick up vpn1
[#] ip link add vpn1 type wireguard
[#] wg setconf vpn1 /dev/fd/63
[#] ip -4 address add 10.68.187.50/32 dev vpn1
[#] ip link set mtu 1380 up dev vpn1
[#] wg set vpn1 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev vpn1 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] iptables-restore -n
/ # wg-quick up vpn2
[#] ip link add vpn2 type wireguard
[#] wg setconf vpn2 /dev/fd/63
[#] ip -4 address add 172.16.0.2/32 dev vpn2
[#] ip link set mtu 1440 up dev vpn2
[#] ip -4 route add 193.32.126.70/32 dev vpn2
/ #
/ # curl https://am.i.mullvad.net/connected
curl: (6) Could not resolve host: am.i.mullvad.net
您确实需要两个 WireGuard 接口;在同一个容器或网络命名空间中运行它们和您的应用程序。由于您的应用程序正在发起请求,因此您无需使用 iptables。只要这两个 VPN 端点本身不在 NAT 之后,您也不需要持久保活。
但是,您确实需要弄乱您的 MTU 设置。普通以太网 MTU 为 1500 字节,而 WireGuard 为 IPv4 数据包增加了 60 字节的开销,因此,除非您和两个 VPN 端点之间的某处有更严格的链接,否则您的外部 WireGuard 接口应使用 1440(1500 - 60),并且您的内部 WireGuard 接口应使用 1380 (1500 - 60 - 60) 的 MTU。
如果您在某处确实有 MTU 限制,请从路径中的最低 MTU 中减去 60 个字节来计算外部接口的 MTU,并为内部接口的 MTU 再减去 60 个字节。有关更多详细信息,请参阅本文的计算内部 MTU部分。
假设您的 VPN 端点的正常 MTU 为 1500,并且您的内部 VPN 端点(VPN 1)例如是 198.51.100.123,请将其用于您的内部 WireGuard 配置:
而且,如果您的外部 VPN 端点 (VPN 2) 是例如 203.0.113.234,请将其用于您的外部 WireGuard 配置:
如果您
AllowedIPs = 0.0.0.0/0
用于内部隧道(如上),请务必添加FwMark = 51820
到外部隧道(如上)。这将防止从外部隧道返回到内部隧道的环路(wg-quick 使用该数据包标记为内部隧道本身设置环路保护——有关更多详细信息,请参阅这篇关于Linux 路由和 wg-quick的文章)。到 VPN 1 的内部隧道嵌套在到 VPN 2 的外部隧道内,当您连接到 google.com 时,您的连接将如下所示:
VPN 2 将您视为外部隧道的来源,VPN 1 将视为内部隧道的目的地;VPN 1 将 VPN 2 视为内部隧道的来源,将 Google 视为隧道流量的目的地;Google 会将 VPN 1 视为隧道流量的来源:
如果您希望流量显示为 You => VPN 1 ~> VPN 2 -> Google,请切换内部和外部隧道。