带有网桥、容器和 systemd-networkd 的 iptables NAT:无转发

带有网桥、容器和 systemd-networkd 的 iptables NAT:无转发

我在 CentOS 7 上配置 iptables NAT 时遇到了一些问题。目前,NAT 后面的客户端可以访问外部 IP,但不能访问外部网络。

我按照本教程设置了我的 NAT,知道它在 Gentoo 和 Arch 上运行良好:

http://www.revsys.com/writings/quicktips/nat.html

概括我的问题:

  • eth0(外部)= 192.168.1.1/24
  • eth1(内部)= 192.168.2.1/24

当我从 192.168.2.2 ping 时:

  • ping 192.168.1.1:成功
  • ping 192.168.1.2 : 不成功
  • ping 8.8.8.8 : 不成功

请注意,我还设置了从 192.168.1.1:80 到 192.168.2.2:80 的端口转发规则。这很有效,根据 Wireshark,我的数据包已成功转发到 192.168.2.2。然后 192.168.2.2 回复,但数据包被丢弃,因此我看到多次 TCP 重传。没有任何“主机管理禁止”消息。

当我尝试从外部连接到 192.168.2.2:80 时,以下是 dropwatch 消息:

1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)

请问有人知道我做错了什么吗?谢谢大家。

编辑 :

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -j ACCEPT
-A FORWARD -d 192.168.2.2/32 -p tcp -m tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

Chain PREROUTING (policy ACCEPT 1270 packets, 123K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   30  1696 DNAT       tcp  --  eth0 any     anywhere             anywhere             tcp dpt:http to:192.168.2.2:80

Chain INPUT (policy ACCEPT 347 packets, 42272 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 6 packets, 431 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 30 packets, 1696 bytes)
 pkts bytes target     prot opt in     out     source               destination                                             
    6   431 MASQUERADE  all  --  any    eth0  anywhere             anywhere 

编辑 :

是的,IP 转发已正确设置。当我从 192.168.2.2 ping 到 192.168.1.2 时,我在 192.168.1.2 上使用 Wireshark 看不到任何传入的数据包。此外,使用 Wireshark 时,我看不到任何从 eth0 离开的数据包。

奇怪的是,当我从 192.168.2.2 成功 ping 192.168.1.1 时,我也看不到 eth0 上有任何 ICMP 数据包传入。

我想我必须补充一些我没有透露的内容,因为我发现它不相关。实际上,我正在尝试将名为 br0 的网络桥接器(此处为我的 eth1)NAT 到本地 LAN。我的服务器 192.168.2.2 位于一个容器中,其中有一个 veth 连接到该桥接器。

我不知道是否应该编辑我的所有帖子以更好地反映情况。我认为我的问题纯粹是一个 iptable 错误,但网络堆栈似乎出了问题,因为在 ping 192.168.1.1 时我应该看到传入的 ICMP 数据包。

当我说我已经在 Gentoo 和 Arch 上进行了此设置时,它也使用了容器,使用 LXC。现在我尝试使用 systemd-nspawn。Selinux 设置为宽容。从我的 CentOS 主机 ping 192.168.2.2 没问题,强制它使用 eth0 不起作用,但这是正常行为。

路线主机:

default via 192.168.1.254 dev eth0 proto static metric 100 
192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.1 
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1 metric 100

路线容器:

default via 192.168.2.1 dev host0 proto static 
192.168.2.0/24 dev host0 proto kernel scope link src 192.168.2.2

答案1

经过一番头痛之后,我终于找到了解决方案......

我使用 systemd-networkd 设置网桥。虽然 net.ipv4.ip_forward 已正确设置为 1,并且我也将 net.ipv4.conf.all.forwarding 设置为 1,但 systemd-networkd 在设置网桥时似乎没有考虑我的默认设置。

Si 最终将 net.ipv4.conf.br0.forwarding 设置为 0。我只需将其设置为 1,现在它就可以工作了。

对于碰巧遇到类似问题的人,请运行此命令:

sysctl -a | grep "\.forwarding" | grep ipv4

确保所有接口都已启用转发。

祝你今天过得愉快。

相关内容