我需要在同一台客户端计算机上配置 2 个不同的 wireguard VPN 网络并将它们嵌套起来,以便当我发出请求时,它会经过 VPN_1,然后是 VPN_2,然后到达目标网站。这里描述了类似的内容: https://mullvad.net/en/help/different-entryexit-node-using-wireguard-and-socks5-proxy/
目前,当 VPN_1 在主机上配置时,我有一个有效的配置,VPN_2 在 docker 容器中配置并通过 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
答案1
您确实需要两个 WireGuard 接口;将它们和您的应用程序都运行在同一个容器或网络命名空间中。由于您的应用程序正在发起请求,因此您无需处理 iptables。只要两个 VPN 端点本身不在 NAT 后面,您也不需要持久性保持连接。
你做但是,您需要调整 MTU 设置。普通以太网 MTU 为 1500 字节,而 WireGuard 为 IPv4 数据包增加了 60 字节的开销,因此,除非您和您的两个 VPN 端点之间有更严格的链接,否则您的外部 WireGuard 接口应使用 1440(1500 - 60)的 MTU,而您的内部 WireGuard 接口应使用 1380(1500 - 60 - 60)的 MTU。
如果某处确实存在 MTU 限制,请从路径中的最低 MTU 中减去 60 字节,以计算外部接口的 MTU,然后再减去 60 字节作为内部接口的 MTU。请参阅本文的计算内部 MTU部分以了解更多详细信息。
假设您到 VPN 端点的正常 MTU 为 1500,并且您的内部 VPN 端点(VPN 1)例如为 198.51.100.123,请将其用于您的内部 WireGuard 配置:
# /etc/wireguard/wg-inner.conf
[Interface]
PrivateKey = <PRIVATE_KEY_1>
Address = 10.68.187.50/32
MTU = 1380
[Peer]
PublicKey = <PUBLIC_KEY_1>
AllowedIPs = 0.0.0.0/0
Endpoint = 198.51.100.123:51820
并且,如果您的外部 VPN 端点(VPN 2)例如是 203.0.113.234,请将其用于您的外部 WireGuard 配置:
# /etc/wireguard/wg-outer.conf
[Interface]
PrivateKey = <PRIVATE_KEY_2>
Address = 172.16.0.2/32
MTU = 1440
FwMark = 51820
[Peer]
PublicKey = <PUBLIC_KEY_2>
AllowedIPs = 198.51.100.123
Endpoint = 203.0.113.234:51820
如果您使用AllowedIPs = 0.0.0.0/0
内部隧道(如上所示),请务必添加FwMark = 51820
到外部隧道(如上所示)。这将防止从外部隧道返回内部隧道的循环(wg-quick 使用该数据包标记为内部隧道本身设置循环保护 - 请参阅此文章Linux 路由和 wg-quick更多细节)。
由于通向 VPN 1 的内部隧道嵌套在通向 VPN 2 的外部隧道内,当您连接到 google.com 时,您的连接将按如下方式工作:
== outer tunnel ==|
~~~~~~~~~~~~~~ inner tunnel ~~~~~~~~~~~~~~~|
You --------------------------------------------------------> Google
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~> VPN 1
==================> VPN 2
VPN 2 会将您视为外部隧道的源,将 VPN 1 视为内部隧道的目的地;VPN 1 会将 VPN 2 视为内部隧道的源,将 Google 视为隧道流量的目的地;而 Google 会将 VPN 1 视为隧道流量的源:
You ==================> VPN 2 ~~~~~~~~~~~~~~~~~> VPN 1 -----> Google
如果您希望流量显示为“您 => VPN 1 ~> VPN 2 -> Google”,请切换内外隧道。