我在 IP 地址为 192.168.1.71 和 abcd 的机器上具有以下 iptables NAT 规则,其中 abcd 代表公共 IP 地址:
iptables -t nat -A PREROUTING -p udp --dport 20001 -j DNAT --to-destination 192.168.1.72:20000
iptables -t nat -A POSTROUTING -p udp -s 192.168.1.72 --sport 20000 -j SNAT --to-source a.b.c.d:20001
当我尝试通过 STUN 查找分配给本地计算机 192.168.1.72 上本地端口 20000 的套接字的公共 IP 地址时,我没有得到 20001,而是始终得到 32018。但是,我得到了正确的 IP 地址 abcd,我需要在 iptables 规则中更改什么?
更新:问题出在我从 STUN 响应计算端口号时。相关问题:规则:
iptables -A INPUT -p udp -j LOG --log-prefix "iptables: "
不记录匹配的数据包,但记录其他数据包。将此规则置于上述两个规则之上或之下没有区别。
答案1
如果第一个数据包始终从网络内部发送,则只需要在 中制定规则POSTROUTING
。Linux 连接跟踪还处理 UDP“关联”,因此它知道如何处理返回数据包。
例如,DNS over UDP 回复数据包使用 Linux 连接跟踪中继到 NAT 后面的客户端。
您的LOG
规则被放入链表INPUT
中filter
,该表仅用于目的地为路由器本身的数据包。由PREROUTING
/POSTROUTING
链处理的数据包永远不会进入INPUT
链。
你的规则看起来应该是这样的:
iptables -t nat -A POSTROUTING -p udp -j LOG --log-prefix "iptables: "
iptables -t nat -A POSTROUTING -p udp -s 192.168.1.72 --sport 20000 -j SNAT --to-source a.b.c.d:20001
https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg是有关数据包如何在 Linux 网络堆栈和不同的 IPTables 链/表内流动的全面图像。
答案2
我在 UDP DNAT 方面遇到了类似的问题。就我而言,连接应该从公共互联网向服务器发起。在服务器上,我有第一个 Linux 桥(带有物理 NIC 成员)。
主机(proxmox 服务器)上的 netfilter 规则将 UDP 端口 500 DNAT 到第二个 Linux 桥(具有 tap NIC 成员)。tap NIC 实际上属于 VM(IPsec 服务器)。路由配置正确(启用了 ip 转发,netfilter 允许所有 FORWARD 数据包以任何方向发送...)。非常奇怪的是,类似的规则适用于 TCP 连接。例如,我在同一个 VM 中有一个 OCSP 服务器,DNAT 运行正常。
更奇怪的是,如果我建立转发到主机上的任何 Linux 网桥的 TCP 连接,UDP DNAT 就会突然开始工作......但不会永远持续下去(只是暂时的)。
Linux 桥接器出了什么问题?如能提供任何帮助,我将不胜感激。
问候,
我自言自语:实际上问题出在我的测试工具上。我使用的是 nmap,但可能使用了错误的参数。我用 netcat 替换了它,发现我的配置没有问题 :) 我用来检查 UDP 500 端口的 netcat 命令是:
nc -vz -u <my-public-ip> 500