我熟悉如何在两个接口之间设置 IP 转发,并且它总是有效。现在我有一个不同的场景,我想设置从本地网桥到输出接口的 IP 转发。
lan0
eno1 < --- > bridge0 -<
lan1
我使用了以下命令:
sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING --out-interface eno1 -j MASQUERADE
iptables -A FORWARD --in-interface bridge0 -j ACCEPT
并尝试从 wlan0 ping 8.8.8.8
使用 tcpdump 我可以看到数据包到达 eno1 并且得到 ping 回复。但它不会从eno1转发回bridge0。
我是否因为使用桥而错过了一些东西?
一些要求的输出:
root@mclaren:/home/ramon# ip -br link
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
eno1 UP f0:d4:e2:eb:c9:9c <BROADCAST,MULTICAST,UP,LOWER_UP>
<BROADCAST,MULTICAST,UP,LOWER_UP>
bridge0 UP a6:13:ed:28:be:7a <BROADCAST,MULTICAST,UP,LOWER_UP>
lan0 UNKNOWN 7a:46:b3:ea:a2:92 <BROADCAST,UP,LOWER_UP>
lan1 UNKNOWN fa:2b:35:57:5c:44 <BROADCAST,UP,LOWER_UP>
root@mclaren:/home/ramon# ip -4 -br address
lo UNKNOWN 127.0.0.1/8
eno1 UP 172.23.1.107/24
bridge0 UP 192.168.0.254/32
root@mclaren:/home/ramon# ip route
default via 172.23.1.254 dev eno1 proto dhcp src 172.23.1.107 metric 100
172.23.1.0/24 dev eno1 proto kernel scope link src 172.23.1.107
172.23.1.254 dev eno1 proto dhcp scope link src 172.23.1.107 metric 100
192.168.0.0/24 dev bridge0 scope link src 192.168.0.254
root@mclaren:/home/ramon# ip -4 neigh
172.23.1.111 dev eno1 lladdr 1c:98:ec:1a:d5:c0 STALE
192.168.0.50 dev bridge0 FAILED
192.168.0.97 dev bridge0lladdr 0a:a0:db:c0:ab:91 STALE
172.23.1.105 dev eno1 FAILED
192.168.0.25 dev bridge0 lladdr 0a:a0:db:c0:41:f4 STALE
172.23.1.130 dev eno1 FAILED
172.23.1.254 dev eno1 lladdr e0:23:ff:d0:b8:22 REACHABLE
172.23.1.163 dev eno1 lladdr e0:70:ea:01:18:6e STALE
192.168.0.33 dev bridge0 lladdr 0a:a0:db:c0:a0:0d STALE
root@mclaren:/home/ramon# bridge link
124: lan0: <BROADCAST,UP,LOWER_UP> mtu 1500 master bridge0 state forwarding priority 32 cost 100
164: lan1: <BROADCAST,UP,LOWER_UP> mtu 1500 master bridge0 state forwarding priority 32 cost 100
root@mclaren:/home/ramon# iptables-save -c
# Generated by iptables-save v1.8.7 on Sat Aug 27 18:53:58 2022
*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [22529:1892750]
:OUTPUT ACCEPT [0:0]
[0:0] -A FORWARD -i bridge0 -j ACCEPT
COMMIT
# Completed on Sat Aug 27 18:53:58 2022
# Generated by iptables-save v1.8.7 on Sat Aug 27 18:53:58 2022
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
[13:990] -A POSTROUTING -o eno1 -j MASQUERADE
[0:0] -A POSTROUTING -o eno1 -j MASQUERADE
COMMIT
# Completed on Sat Aug 27 18:53:58 2022
答案1
您的防火墙规则集阻止返回流量:
*filter :INPUT ACCEPT [0:0] :FORWARD DROP [22529:1892750] :OUTPUT ACCEPT [0:0] [0:0] -A FORWARD -i bridge0 -j ACCEPT COMMIT
[...]
这允许从桥接口接收到的流量到达其他任何地方。但没有任何方法允许从任何地方接收到的流量到达桥接口。因此,当 ping 回复到达时,将应用默认策略:丢弃。
你可以简单地这样做:
iptables -A FORWARD -o bridge0 -j ACCEPT
或者你可以使用状态防火墙允许(仅)回复:
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
除其他事项外(例如 FTP 等协议的备用数据流,这需要额外的设置)有关的流量包含相关的 ICMP 错误,因此可以接收回 UDP 错误,或者路径 MTU 发现可以正常工作。
这个答案中没有任何内容与桥的使用有关。
有了 Docker,你可能不得不考虑是否应该改为插入这些规则位于 DOCKER-USER 链中(因为 Docker 可能会向其附加某些内容)而不是 FORWARD 链(请参阅那里有详细信息知道你是否需要它)。
iptables -N DOCKER-USER || true # so it works whether Docker was started before or not
iptables -I DOCKER-USER 1 -o bridge0 -j ACCEPT
iptables -I DOCKER-USER 2 ...
或者
iptables -N DOCKER-USER || true
iptables -I DOCKER-USER 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
...
现在有了 Docker 的存在,事情能与使用桥而不是普通接口相关。然后可能应该将其添加到 FORWARD 中或可能添加到 DOCKER-USER 中,否则 lan0 和 lan1 之间的桥接流量可能会中断:
iptables -A -m physdev --physdev-is-bridged -j ACCEPT
关于这个 Docker 问题的相关问题:这里,这里或者那里。这是一个相当高级的话题。简而言之:不要在 Docker 已更改网络设置/防火墙设置的系统上进行网络实验。