使用 Linux Bridge 的转发和路由问题

使用 Linux Bridge 的转发和路由问题

我在虚拟机 (Ubuntu 18.04) 中运行两个容器 (A 和 B)。为了进行网络模拟,我将数据包从 A 路由到 B (此部分有效)。我想要做的是允许 A 和 B 与外界通信。因此,我会:

A ---- B ---- Host VM --- Host --- Internet

到目前为止我已经这样做了:

ip link add name br_routing type bridge
ip link set dev br_routing up

然后添加另一个虚拟接口,以便容器 B 有一个接口可以到达主机虚拟机网络:

ip link add vm_side_iface type veth peer name containerb_side_iface

将接口添加到桥接器

ip link set dev vm_side_iface master br_routing

设置容器内的网桥和接口的 IP

ip addr add 192.168.10.1/24 dev br_routing
ip addr add 192.168.10.2/24 dev vm_side_iface

激活虚拟机端接口

ip link set vm_side_iface up
ip link set containerb_side_iface netns $container_pid

然后在容器 B 网络命名空间内:

ip addr add 192.168.10.2/24 broadcast 192.168.10.255 dev containerb_side_iface
ip route add default via 192.168.10.1 dev containerb_side_iface

此时,我可以从主机虚拟机 ping A 和 B

但是我无法从 A 或 B ping 通网桥。错误似乎来自路由,因此它是这样的:B 路由表:

10.11.1.0/24 dev eth0  proto kernel  scope link  src 10.11.1.2
10.22.0.0/16 via 10.11.1.1 dev eth0
192.168.10.0/24 dev containerb_side_iface  proto kernel  scope link  src 192.168.10.2

主机虚拟机路由表:

default via 10.0.2.2 dev enp0s3 proto dhcp metric 100
10.0.2.0/24 dev  enp0s3 proto kernel scope link src 10.0.2.15 metric 100 #Irrelevant here
10.11.0.0/16 via 192.168.10.2 dev br_routing #Route to reach B
10.22.0.0/16 via 192.168.10.2 dev br_routing #Route to reach A
192.168.10.0/24 dev br_routing proto kernel scope link src 192.168.10.1 #This seems odd
192.168.10.0/24 dev router_0 proto kernel scope link src 192.168.10.2 #This seems odd

我的第二个猜测是我的路由表,这是我尝试过的:

iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
iptables -A FORWARD -i enp0s3 -o vm_side_iface, -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i vm_side_iface, -o enp0s3 -j ACCEPT
iptables -A FORWARD -i enp0s3 -o vm_side_iface, -j ACCEPT

我也尝试更换虚拟机侧接口经过br_routing但无论如何都行不通。此外,规则未被使用(0 个接受的数据包,0 个丢弃的数据包)。这些是 VM 中配置的唯一规则。无论如何,从主机 VM 到 A/B 的 ping 在没有这些规则的情况下也能正常工作。

最后,modprobe br_netfilter并且刷新 /etc/sys/net/bridge 里面的文件不会改变任何东西。

无效的方法:

ping from A or B to HOST VM
ping from A or B to vm_side_iface
ping from A or B to br_routing

有效的方法:

ping from HOST VM to A or B

我注意到消息到达了网桥(tcpdump -i br_routing)但没有转发到 enp0s3 接口。

有什么猜测吗?

答案1

我设法通过使用在启动没有网络参数的docker容器时默认创建的docker0网桥来使其工作

docker run -itd image_name

这座桥和我正在建造的那座桥是一样的,但不知何故,这座桥却能正常运作。

相关内容