我正在尝试使用 VPS 通过 VPN 隧道将 80,443 端口转发到本地 Web 服务器进行测试,同时保持原始源公共 IP 不变。这里的主要问题是路由,因为边缘路由设备将有效地看到 2 个带有公共 IP 的接口(真正的 WAN 和 VPN 接口)。
显然,简单的解决方案是仅通过 vpn 隧道的 SNAT 流量,但我想深入了解 Web 流量的真正来源,加上我做的 NAT 越多,我引入系统的开销就越大。此外,我避免在 VPS 上放置任何反向代理,因为我拒绝在遍历 VPS 时随时解密网络流量。
现在开始测试:使用的 IP:Web SRV:192.168.0.2,VPS Wireguard Addr:192.168.200.1,Router Wireguard Addr:192.168.200.2。
我设置了一个虚拟测试网络,其中包含几个 Debian 11 机器作为 VPS 服务器、本地路由器和 Web 服务器。
在 VPS 上,我的 DNAT 流量从端口 80,443 上的接口传入:
iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport –dports 80,443 -j DNAT –to-destination 192.168.0.2
我已经设置 sysctl.conf 来启用 ipv4 转发。我在 VPS 上有一条静态路由,告诉我从哪里到达 192.168.0.2:
ip route add 192.168.0.2/32 via 192.168.200.2 dev wg0
在本地路由器上,我根据接口在网上找到了一些基于回复的规则:
echo 200 vpsrt >> /etc/iproute2/rt_tables
ip rule add from 192.168.200.2 table vpsrt prio 1
ip route add default via 192.168.200.1 dev wg0 table vpsrt
由于 VPN 隧道位于路由器上,因此 Web 服务器已经配置了其默认网关,因此本地路由器和 Web 服务器之间的返回流量根本不会改变。
VPS 上的 wg0.conf(充当服务器):
[Interface]
PrivateKey=*
Address=192.168.200.1/30
ListenPort=50000
[Peer]
PublicKey=*
AllowedIPs=192.168.200.2/32,192.168.0.2/32
路由器上的 wg0.conf(作为客户端):
[Interface]
Address=192.168.200.2/32
PrivateKey=*
[Peer]
Endpoint=PUBIPVPS:50000
PublicKey=*
AllowedIPs=172.20.200.0/30
我已经验证了 Wireguard 隧道的工作原理。我可以分别在每个设备上 ping 192.168.200.1 和 .2,wg show 说握手完成并且双向数据正在流动。
做一些 PCAP,通过 VPS 的流量是正确的。VPS 上 wg0 上的 Tcpdump 显示发往 192.168.0.2 端口 443 的数据包。VPS 上的 WG Show 说它正在传输 1.3Kb,但路由器上的 WG Show 说它只收到了 500 字节(测试 ping)。路由器 WAN 接口上的 Tcpdump 显示 Wireguard 数据包正在到达路由器。但是路由器 wg0 上的 Tcpdump 显示它没有收到任何数据包。
我很确定问题是 Wireguard 正在默默地丢弃具有未在 AllowedIPs (在路由器上)中配置的源 IP 的数据包。但问题是我不能将 0.0.0.0/0 放在路由器 wg0.conf 上,因为它会开始使用隧道作为整个网络的默认网关!
是否不可能使用 Wireguard 作为非默认网关进行基于源的路由?使用其他隧道软件是否有任何潜在的解决方法?我真的很喜欢 Wireguard 的速度,但是如果没有 SNAT/Masquerade,它会变得非常有限。
更新: 刚刚找到这篇文章: https ://techoverflow.net/2021/07/09/what-does-wireguard-allowedips-actually-do/ 它解释说,wireguard“防火墙”和路由使用 AllowedIPs 绑定在一起。
再做一点测试,我可以简单地将路由器上的 AllowedIPs 放到 0.0.0.0/0 并在 wg0.conf 中添加一个 postup 规则来删除默认网关路由,而只添加一个静态路由到隧道 IP。(不幸的是,wireguard 选择将“防火墙”和路由整合到一个选项中)
路由器 wg0 接口上的 Tcpdump 显示数据包现在正在穿越隧道。路由器 LAN 接口上的 Tcpdump 显示数据包已传输出去,并且 Web 服务器正在响应。但现在的问题是那些基于接口源的路由规则似乎无法正常工作,因为 Web 服务器的响应没有被传递到 wireguard 隧道中。
路由器 WAN 接口上的 Tcpdump 显示 Web 服务器 syn-acks 被推出该网关。所以现在我的问题在于我上面提到的基于源的路由规则。基于源的路由超出了我的知识范围,因此非常感谢您提供任何帮助。
你已经完成了 90% 的路。在路由器上设置自定义
vpsrt
路由表时:您应该在第二行使用Web 服务器的IP 地址,而不是路由器的IP 地址:
这将指示您的路由器将所有流量从您的 Web 服务器发送到 WireGuard 隧道。只要您
AllowedIPs=0.0.0.0/0
在路由器的 WireGuard 配置中作为 VPS 服务器对等条目的一部分,WireGuard 隧道就会接受该流量,并将其发送回 VPS 服务器。此外,如果您在路由器的 WireGuard 配置中指定表,则不需要上面的第三行:
使用该设置,
wg-quick
会将默认路由添加到您的自定义vpsrt
表中,而不是在全局范围内弄乱您的默认路由。此外,如果您不想将所有流量从 Web 服务器路由到 VPS(仅来自 TCP 端口 80 和 443 的响应),您可以使用这些规则代替上面的第二行:
您可以考虑使用 VRF(虚拟路由和转发)。VRF 用于使用自己的默认网关配置单独的路由表。您可以将您的wireguard 接口和您的Web 服务器连接到VRF,并且流量将与当前存在的连接分开。
这是使用 VRF 的一个很好的例子:https ://interpip.es/linux/creating-a-vrf-and-running-services-inside-it-on-linux/