我有两个系统 A 和 B。A 是 TCP 客户端,它向 B 上的 TCP 服务器发送消息。
------------------ --------------------------
System A System B
192.168.0.5 wlan0 192.168.0.3 wlan0
127.0.0.1 lo 127.0.0.1 lo
TCP Client <------------> TCP Server on 127.0.0.1
------------------ ----------------------------
TCP 客户端向 192.168.0.3 发送消息。
由于 TCP 服务器在系统 B 的端口 8000 上的 127.0.0.1 上运行,因此应该将其重定向到 B 的本地接口。
于是我写了如下的ip表规则,但是我B的Server收不到任何消息,哦对了,这两个系统都是Ubuntu linux系统。
这是我在系统 B 上所做的:
#Enable IP Forwarding for NAT
echo "1" > /proc/sys/net/ipv4/ip_forward
#Flush all iptable chains and start afresh
sudo iptables -F
#Forward incoming packets on 192.168.0.3 at wlan0 interface to 127.0.0.1
sudo iptables -t nat -A PREROUTING -p tcp -i wlan0 -d 192.168.0.3 --dport 8000 -j DNAT --to 127.0.0.1:8000
#Explicitly allow incoming connections on port 8000
sudo iptables -A INPUT -i wlan0 -p tcp --dport 8000 -m state --state NEW,ESTABLISHED -j ACCEPT
#Explicitly allow outgoing messages from port 8000
sudo iptables -A OUTPUT -o wlan0 -p tcp --sport 8000 -m state --state ESTABLISHED -j ACCEPT
然后我在 B 上启动服务器并从 A 上的 TCP 客户端发送一条消息。我可以在 wireshark 上看到来自 wlan0 上的 192.168.0.5 的数据包,但它们从未被转发 :(
请帮忙。
更新:
在听取了这里专家的意见后,我制定了一个更为现实的“NAT”场景来应用转发规则,但仍然存在问题:我在较新的帖子中解释了这一点: Iptables:转发数据包不起作用
答案1
这是一个完全没有答案的答案。
正如 Jens Bradler 在他的评论中所说,这里最简单的做法是将服务绑定到端口 8000 上的公共 IP 地址,而不是 NAT 连接。您可以通过 iptables 规则保护对单个服务器 A 的访问,如下所示;
-A INPUT -s 192.168.0.5/32 -p tcp -m tcp --dport 8000 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8000 -j REJECT
答案2
Tom H 的非答案答案更好,但如果你不喜欢它,这里有一个直接答案:
抱歉,我的iptables
技能最好是能够修改、测试、检查、记录、重复……而且我没有你的系统可以玩,但无论如何,这是我的建议。你可能需要使用日志进行调试。
改变重定向的方向,如 Jens Bradler 所述:
echo "1" > /proc/sys/net/ipv4/ip_forward
证明它是正确的
cat /proc/sys/net/ipv4/ip_forward
猫的输出:
1
也使用 FORWARD 表添加一条 ACCEPT 规则。
sudo iptables -A FORWARD -i wlan0 -p tcp --dport 8000 -j ACCEPT
从传入规则中删除“-m state”内容(可选...我认为没有必要):
sudo iptables -A INPUT -i wlan0 -p tcp --dport 8000 -j ACCEPT
可能在您添加“ESTABLISHED”的任何地方,也应该有“RELATED”(不确定,但我认为启动连接的返回数据包是相关的,但未建立)。
sudo iptables -A OUTPUT -o wlan0 -p tcp --sport 8000 -m state --state RELATED,ESTABLISHED -j ACCEPT
与上面的接受规则相配合的 FORWARD 规则,是另一个 FORWARD 的逆转。
sudo iptables -A FORWARD -o wlan0 -p tcp -s 127.0.0.1 --sport 8000 -m state --state RELATED,ESTABLISHED -j ACCEPT
不要使用 Wireshark,而要使用-j LOG
。
首先检查是否已经有 LOG 规则(默认规则比以下规则更好...但是您使用了 flush ;我的规则会向您的服务器发送大量垃圾邮件):
sudo iptables --list --line-numbers -v
sudo iptables -t nat --list --line-numbers -v
如果没有,则添加它们:
sudo iptables -A INPUT -j LOG
sudo iptables -A OUTPUT -j LOG
sudo iptables -A FORWARD -j LOG
sudo iptables -t nat -A PREROUTING -j LOG
查看日志
tail -F /var/log/firewall
# or if that file doesn't exist:
tail -F /var/log/messages
答案3
你永远无法表演-j DNAT --to 127.0.0.1
。
127.0.0.1 是一个超级特殊的地址;它只接受来自 127.0.0.1 的连接。
@汤姆 H的答案是您应该设置服务器的方式。
答案4
系统B:
sysctl -w net.ipv4.conf.wlan0.route_localnet=1
iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 8080 -j DNAT --to 127.0.0.1