我正在使用 Ubuntu 20.04。我设置了以下 iptables 规则:
sudo iptables -t nat -A POSTROUTING -d 192.168.10.162 -j MASQUERADE
sudo iptables -t nat -A PREROUTING -p tcp --dport 445 -j DNAT --to-destination 192.168.10.162:445
192.168.10.162 是另一台 Ubuntu 服务器,版本为 18.04,也运行一些 smb 服务器。
当我运行 $sudo iptables -t nat -L -v 时,它显示以下内容:
Chain PREROUTING (policy ACCEPT 3 packets, 249 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- any any anywhere anywhere tcp dpt:microsoft-ds to:192.168.10.162:445
Chain INPUT (policy ACCEPT 1 packets, 149 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any any anywhere 192.168.10.162
是不是意味着我的 nat 命令已经生效了?也就是说发往 445(smb)端口的数据包会被转发到 192.168.10.162:445 呢?
我通过 $sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward 启用了 ip forward。我在 Ubuntu 20.04 机器上安装了一个 smb 服务器,并使用另一台 Win10 PC 访问它的共享目录。然后我发现我的访问、删除目录下的文件或将文件复制到目录,都没有显示我添加的两个 nat 规则的记录迹象。
然后,我在 Ubuntu 20.04 机器上挂载 192.168.10.162 的 smb 共享目录,并按照上述方式访问其自己的 smb 共享目录后,仍然没有看到 PREROUTING 规则中的记录,但是 POSTROUTING 规则中有一些记录。
Chain PREROUTING (policy ACCEPT 176 packets, 16007 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- any any anywhere anywhere tcp dpt:microsoft-ds to:192.168.10.162:445
Chain INPUT (policy ACCEPT 74 packets, 10704 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 19 packets, 1620 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 18 packets, 1560 bytes)
pkts bytes target prot opt in out source destination
1 60 MASQUERADE all -- any any anywhere 192.168.10.162
看来 mount 命令可能触发了我的 POSTROUTING 规则上的记录。我还测试了 ping 到 192.168.10.162 触发了此规则上的记录。但为什么我的 PREROUTING 规则上没有捕获任何 pkts 或字节?即使我将一个大文件复制到 Ubuntu 20.04 机器的 smb 共享目录中。
[更新] 我尝试将所有 dport 为 8080 的数据包转发到运行 Web 服务器的 192:168.10.162:80。然后我使用 Win10 PC 通过 http://[ip 地址]:8080 访问该机器(Ubuntu 20.04),它会重定向到 Web 服务器。iptables nat PREROUTING 和 POSTROUTING 显示记录。
Chain PREROUTING (policy ACCEPT 551 packets, 41812 bytes)
pkts bytes target prot opt in out source destination
5 260 DNAT tcp -- any any anywhere anywhere tcp dpt:http-alt to:192.168.10.162:80
Chain INPUT (policy ACCEPT 77 packets, 10563 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 12 packets, 922 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 12 packets, 922 bytes)
pkts bytes target prot opt in out source destination
5 260 MASQUERADE tcp -- any any anywhere 192.168.10.162 tcp dpt:http
[更新] 我使用 $tcptrack 确认数据包确实发送到了 Ubuntu 20.04 的 445 端口。同样,没有显示任何数据包被 nat PREROUTING 捕获。
答案1
您正在尝试 SMB 服务器,但您没有对所有 SMB 重新连接的端口进行 DNAT。您还需要以下端口:137,138,139
您可以看到一个关于端口及其对应的 TCP/UDP 协议的表格这里。
sudo iptables -t nat -A POSTROUTING -d 192.168.10.162 -j MASQUERADE
sudo iptables -t nat -A PREROUTING -m multiport --dports 137,138,139,445 -j DNAT --to-destination 192.168.10.162
当然,第二条规则不会检查每个端口的正确 TCP/UDP 协议。
如果您希望您的表既适用于这台机器,也适用于这台机器路由的表,那么您必须对 OUTPUT 链和 PREROUTING 链执行相同的操作:
sudo iptables -t nat -A OUTPUT -m multiport --dports 137,138,139,445 -j DNAT --to-destination 192.168.10.162
这是因为从您自己的机器生成的数据包不会经过PREROUTING,而是直接进入OUTPUT,然后再进入POSTROUTING。
以下是nftables 的钩子可以帮助你理解这一点:
答案2
很抱歉地告诉大家,我犯了一个低级错误。我忘记在 Linux 机器上启用 IPFORWARD 了。在我运行
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
有用。