我正在尝试设置一个 OpenVPN VPN,它将通过 OpenVPN 服务器将一些(但不是全部)流量从客户端传输到互联网。
我的 OpenVPN 服务器在 eth0 上有一个公共 IP,并且正在使用 tap0 创建一个本地网络 192.168.2.x。我有一个从本地 IP 192.168.1.101 连接并获取 VPN IP 192.168.2.3 的客户端。
在服务器上,我运行:
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE
在客户端上,默认仍然通过 192.168.1.1 进行路由。为了将它指向 HTTP 的 192.168.2.1,我跑了
ip rule add fwmark 0x50 table 200
ip route add table 200 default via 192.168.2.1
iptables -t mangle -A OUTPUT -j MARK -p tcp --dport 80 --set-mark 80
现在,如果我尝试访问客户端上的网站(例如 wget google.com),它就会挂在那里。在服务器上,我可以看到
$ sudo tcpdump -n -i tap0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tap0, link-type EN10MB (Ethernet), capture size 96 bytes
05:39:07.928358 IP 192.168.1.101.34941 > 74.125.67.100.80: S 4254520618:4254520618(0) win 5840 <mss 1334,sackOK,timestamp 558838 0,nop,wscale 5>
05:39:10.751921 IP 192.168.1.101.34941 > 74.125.67.100.80: S 4254520618:4254520618(0) win 5840 <mss 1334,sackOK,timestamp 559588 0,nop,wscale 5>
其中 74.125.67.100 是它为 google.com 获得的 IP。
为什么 MASQUERADE 不工作?更准确地说,我看到源显示为 192.168.1.101 - 不应该有什么表明它来自 VPN 吗?
编辑:一些路线[来自客户端]
$ ip route show table main
192.168.2.0/24 dev tap0 proto kernel scope link src 192.168.2.4
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.101 metric 2
169.254.0.0/16 dev wlan0 scope link metric 1000
default via 192.168.1.1 dev wlan0 proto static
$ ip route show table 200
default via 192.168.2.1 dev tap0
您可以发布ip route show table main和ip route show table 200的输出吗?我怀疑您在“200”表中缺少几条路线。您的“200”路由表应该与“主”表具有几乎相同的路由,唯一的区别是默认路由。
我看到你更新了,我相信我最初的建议是正确的。请注意您的主表如何为您的本地网络和 vpn 链接提供“范围链接”路由?这些路线也必须添加到“200”表中。
除了您使用的其他命令之外,请尝试运行这些命令。
如果您想编写这些路线的创建脚本,您可以使用它。它将所有“范围链接”路由从主路由表复制到您的另一个表中。
另一个更新。我只是注意到我之前错过了一些相当明显的东西。
您的 MASQ 声明似乎正在处理 eth0。从您发布的路由表中,您的输出设备不是 eth0。而不是这个。
您可能应该只使用这样的语句。
在服务器上尝试:
我认为,这将暂时启用它。如果有效,请添加:
到您的 /etc/sysctl.conf 以使其永久化。
有两件事是错误的:
首先,在客户端上,我需要将源 SNAT 转换为实际 IP。
其次,反向路径过滤器阻止了返回的数据包,因为它认为它们被欺骗了。
echo 0 > /proc/sys/net/ipv4/conf/tun0/rp_filter
修复了