如何使用iptables制定IP转发规则

如何使用iptables制定IP转发规则

我有两个系统 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

相关内容