我正在使用 iptables 并尝试完成一个非常简单的任务:将 Ubuntu 上端口 8888 的流量转发到 IP 为 172.21.16.1 和端口 5000 的另一台服务器。
在我的环境中,我有一个 Windows 工作站。Ubuntu 由 Hyper-V 提供服务。我的 Windows 工作站有多个网络接口,包括由 Hyper-V 创建的。IP 地址分配给172.21.16.1
。Ubuntu 有一个 IP 172.21.26.237
。
我在 Windows 工作站上启动了一个简单的 Web 服务器,它监听端口 5000 的 HTTP 请求。如果打开一个页面http://172.21.16.1:5000在浏览器中(无论它是 Ubuntu 还是 Windows)我都能看到预期的输出。
我查看了几篇文章,看起来应该很简单直接。我执行了以下命令:
sudo iptables -A PREROUTING -t nat -p tcp --dport 8888 -j DNAT --to-destination 172.21.16.1:5000
sudo iptables -A POSTROUTING -t nat -p tcp --dport 8888 -j SNAT --to-source 172.21.26.237
如果我打开页面http://172.21.26.237:8888/从我的 Windows 工作站 – 超时。
我检查过的内容:
(1)sysctl net.ipv4.ip_forward
退货net.ipv4.ip_forward = 1
(2)iptable-save 给出以下内容:
# Generated by iptables-save v1.8.4 on Sun Jul 19 20:15:37 2020
*filter
:INPUT ACCEPT [1066:122755]
:FORWARD ACCEPT [90:4680]
:OUTPUT ACCEPT [255:18156]
COMMIT
# Completed on Sun Jul 19 20:15:37 2020
# Generated by iptables-save v1.8.4 on Sun Jul 19 20:15:37 2020
*nat
:PREROUTING ACCEPT [233:25903]
:INPUT ACCEPT [198:18944]
:OUTPUT ACCEPT [23:1798]
:POSTROUTING ACCEPT [41:2734]
-A PREROUTING -p tcp -m tcp --dport 8888 -j DNAT --to-destination 172.21.16.1:5000
-A POSTROUTING -p tcp -m tcp --dport 8888 -j SNAT --to-source 172.21.26.237
COMMIT
# Completed on Sun Jul 19 20:15:37 2020
(3)来自以下来源的痕迹tcpdump ..... port 8888
:
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
22:18:38.078418 IP (tos 0x0, ttl 128, id 35408, offset 0, flags [DF], proto TCP (6), length 52)
172.21.16.1.63351 > 172.21.26.237.8888: Flags [S], cksum 0xa604 (correct), seq 2988342963, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
22:18:38.078566 IP (tos 0x0, ttl 128, id 35409, offset 0, flags [DF], proto TCP (6), length 52)
172.21.16.1.63352 > 172.21.26.237.8888: Flags [S], cksum 0x04c0 (correct), seq 3168343356, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
22:18:38.329143 IP (tos 0x0, ttl 128, id 35410, offset 0, flags [DF], proto TCP (6), length 52)
172.21.16.1.63353 > 172.21.26.237.8888: Flags [S], cksum 0x58e7 (correct), seq 371877827, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
22:18:39.084897 IP (tos 0x0, ttl 128, id 35411, offset 0, flags [DF], proto TCP (6), length 52)
(4)来自以下来源的痕迹tcpdump ..... port 5000
:
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
22:19:34.468908 IP (tos 0x0, ttl 127, id 35424, offset 0, flags [DF], proto TCP (6), length 52)
172.21.16.1.63367 > 172.21.16.1.5000: Flags [S], cksum 0x09ca (correct), seq 3528594630, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
22:19:34.468992 IP (tos 0x0, ttl 127, id 35425, offset 0, flags [DF], proto TCP (6), length 52)
172.21.16.1.63368 > 172.21.16.1.5000: Flags [S], cksum 0x3138 (correct), seq 561028665, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
22:19:34.729633 IP (tos 0x0, ttl 127, id 35426, offset 0, flags [DF], proto TCP (6), length 52)
172.21.16.1.63369 > 172.21.16.1.5000: Flags [S], cksum 0xc4c0 (correct), seq 920253766, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
22:19:35.473332 IP (tos 0x0, ttl 127, id 35428, offset 0, flags [DF], proto TCP (6), length 52)
(5)以下是curl -v url:8888
在 Windows 上执行的输出:
> curl -v 172.21.26.237:8888
* Rebuilt URL to: 172.21.26.237:8888/
* Trying 172.21.26.237...
* TCP_NODELAY set
* connect to 172.21.26.237 port 8888 failed: Timed out
* Failed to connect to 172.21.26.237 port 8888: Timed out
* Closing connection 0
curl: (7) Failed to connect to 172.21.26.237 port 8888: Timed out
可惜,还是没有线索。
答案1
DNAT 看起来不错,但我认为我应该选择 SNAT
-A POSTROUTING -p tcp -m tcp --dport 5000 -j SNAT --to-source 172.21.26.237
代替
-A POSTROUTING -p tcp -m tcp --dport 8888 -j SNAT --to-source 172.21.26.237
我的意思是,由于 PREROUTING 将端口从 8888 更改为 5000,因此在该阶段之后的任何地方期望 8888 是没有意义的。