我已经创建了这个桥接设备
ip link add dev br0 type bridge
ip addr add 172.16.0.254/16 broadcast 172.16.255.255 dev br0
ip link set br0 up
sysctl -w net.ipv4.conf.br0.forwarding=1
此设备由虚拟机使用,但我似乎无法让它按我想要的方式工作。我尝试使用以下 iptables 规则。
iptables -A FORWARD -o br0 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A POSTROUTING -t nat -s 172.16.0.0/16 -j MASQUERADE
有了这些规则,虚拟机就无法访问互联网。如果我允许一切,它就可以正常工作。
iptables -A FORWARD -i br0 -j ACCEPT
模块conntrack
已加载。我只是在测试设置规则,允许转发虚拟机发起的任何流量,但拒绝所有其他传入流量。
答案1
这可能是因为你有-i
和-o
倒退,所以你的规则只允许“新”数据包到虚拟机,但没有从他们。
也许我误解了 iptables 上的输入和输出是什么?输入不就是从主机传递到网桥的传入/响应吗?
不。如果你说的是 -i/-o 选项,那么它们不是一般的“输入/输出”——它们的意思是“输入/输出界面转发的数据包有两个都填写“输入”和“输出”字段,以及您与这些选项一起指定的实际接口最终构成规则“输出到 VM”与“输出到 Internet”,或“从 VM 输入”等。
例如,如果您的虚拟机想要启动与 Google 的连接,它将首先发送一个 SYN 数据包,主机通过 (-i) br0 接收该数据包,然后即将通过 (-o) wlan0 转发该数据包。因此,允许“来自虚拟机的 NEW”的规则应该是
-i br0
。随后,来自 Google 的回复数据包将通过 (-i) wlan0 接收,取消 NAT,然后通过 (-o) br0 转发到 VM。
但是第三个数据包将再次来自(-i)br0,等等。因此,‘ESTABLISHED’数据包需要在两个方向上都被允许,并且您可以只制定一个规则,而无需任何接口检查。
(如果你说的是 iptables 链,那么 'INPUT' 就是发往主机自己的 IP 地址的数据包,也就是不是转发到其他任何地方。(此检查是在路由期间进行的,因此它发生在 conntrack 已完成其 un-NAT 之后。)类似地,“OUTPUT”用于主机本身生成的数据包。)