![通过 VPN 提供对本地 Web 服务器的公共访问](https://linux22.com/image/610751/%E9%80%9A%E8%BF%87%20VPN%20%E6%8F%90%E4%BE%9B%E5%AF%B9%E6%9C%AC%E5%9C%B0%20Web%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E5%85%AC%E5%85%B1%E8%AE%BF%E9%97%AE.png)
我在两台服务器之间建立了一条 VPN 隧道:VPS-A 和 VPS-B 分别具有(虚构的)公共 IP 地址:66.55.44.33 和 77.88.55.66,以及 VPN 端点 10.0.1.1 和 10.0.2.1。
VPS-A 上运行着一个 Web 服务器。我可以毫无问题地通过 SSH 连接到 VPS-B,并在通过 curl 向 10.0.1.1 发出 HTTP 请求时收到响应,例如:
curl http://10.0.1.1/
我还可以在任何连接到互联网的计算机上打开浏览器并成功打开
http://66.55.44.33/
...但我希望能够通过向 VPS-B 发送请求来访问 VPS-A 上的 Web 服务器,即
http://77.88.55.66/
现在,我在 VPS-B 上添加了以下规则(编辑以显示正确的规则)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.1.1:80
...当我在端口 80 上执行 时tcpdump
,我可以清楚地看到请求如何http://77.88.55.66/
正确转发到http://10.0.1.1
。但是,VPS-A 上的 Web 服务器似乎没有确认 TCP 请求。以下是 tcpdump 所显示的具体内容:
2013-04-27 03:45:15.001564 IP 45.248.82.171.51377 > 10.0.1.1.80: S 791893048:791
2013-04-27 03:45:15.252571 IP 45.248.82.171.51378 > 10.0.1.1.80: S 670490211:670
2013-04-27 03:45:18.001526 IP 45.248.82.171.51377 > 10.0.1.1.80: S 791893048:791
2013-04-27 03:45:18.258666 IP 45.248.82.171.51378 > 10.0.1.1.80: S 670490211:670
..而对于通过 VPN 发送的请求:
2013-04-27 04:26:57.464859 IP 10.0.2.1.33258 > 10.0.1.1.80: S 2369100373:2369100373(0) win 5744 <mss 1436,sackOK,timestamp 121795122 0,nop,wscale 7>
2013-04-27 04:26:57.464913 IP 10.0.1.1.80 > 10.0.2.1.33258: S 3524730589:3524730589(0) ack 2369100374 win 5744 <mss 1436,nop,nop,sackOK,nop,wscale 7>
2013-04-27 04:26:57.532428 IP 10.0.2.1.33258 > 10.0.1.1.80: . ack 1 win 45
我对 Linux 还很陌生,所以我肯定我做错了什么,但我不知道具体是什么。我尝试搜索类似的问题,但没有找到任何东西。如果有人能给我指出一个有用的资源或给我一个实际的例子——那就太好了。
感谢您花时间阅读我的帖子!
答案1
您的描述一定不完整。INPUT 和 FORWARD 中的规则不会让发往 77.88.55.66 的数据包转而前往 10.0.1.1。只有表链DNAT
中的目标才有可能做到这一点。显然有这样的规则。PREROUTING
nat
为了成功重定向,您不需要 INPUT 中的规则,因为重定向系统不会接收这些数据包。
没有 SNAT 的 DNAT 的问题(就像您的情况一样)在于,系统在路由答案时通常不关心通过哪个接口到达。您的 VPS-A 看到来自 45.248.82.171 的连接打开,如果它愿意与该客户端通信,那么它会发送响应 - 是的,45.248.82.171。客户端已将 SYN 数据包发送到 77.88.55.66 并收到来自 66.55.44.33 的 SYN ACK,显然只是在想 WTF?为什么是来自 66.55.44.33?因为回复不是通过隧道发送的,因为 VPS-A 的路由配置告诉它不要通过隧道将数据包发送到此目的地。如果他们通过隧道返回,那么 VPS-B 会将源地址重写为其自己的地址,一切都会好起来。
因此,您要么必须使用 iptables 来标记通过隧道的连接(为什么要通过隧道?),将连接标记重写为数据包标记,然后使用高级路由和此数据包标记来通过隧道发送这些数据包。或者,您可以同时进行 NAT 的两端,在通过隧道从 VPS-B 发送数据包之前进行 SNAT,然后以简单的方式从 VPS-A 取回数据包。缺点:Web 服务器日志显示“错误”的 IP 地址(始终为 10.0.2.1)。
顺便说一句:10.0.2.1 和 10.0.1.1 是同一个 VPN 的奇怪的端点地址,不是吗?