将 LXC 容器桥接到主机 eth0,以便它们可以拥有公共 IP

将 LXC 容器桥接到主机 eth0,以便它们可以拥有公共 IP

更新:

我在那里找到了解决方案: http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge#No_traffic_gets_trough_.28except_ARP_and_STP.29

 # cd /proc/sys/net/bridge
 # ls
 bridge-nf-call-arptables  bridge-nf-call-iptables
 bridge-nf-call-ip6tables  bridge-nf-filter-vlan-tagged
 # for f in bridge-nf-*; do echo 0 > $f; done

但我想听听专家对此的意见:禁用所有 bridge-nf-* 是否安全?它们在这里做什么?

更新结束

我需要将 LXC 容器桥接到我的主机的物理接口(eth0),阅读有关该主题的大量教程、文档和博客文章。

我需要容器有自己的公共 IP(我之前已经做过 KVM/libvirt)。

经过两天的搜索和尝试,我仍然无法让它与 LXC 容器一起工作。

主机运行新安装的 Ubuntu Server Quantal (12.10),仅安装了 libvirt(我在这里没有使用)和 lxc。

我使用以下命令创建了容器:

lxc-create -t ubuntu -n mycontainer

所以他们也运行 Ubuntu 12.10。

/var/lib/lxc/mycontainer/config 的内容是:


lxc.utsname = mycontainer
lxc.mount = /var/lib/lxc/test/fstab
lxc.rootfs = /var/lib/lxc/test/rootfs


lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.name = eth0
lxc.network.veth.pair = vethmycontainer
lxc.network.ipv4 = 179.43.46.233
lxc.network.hwaddr= 02:00:00:86:5b:11

lxc.devttydir = lxc
lxc.tty = 4
lxc.pts = 1024
lxc.arch = amd64
lxc.cap.drop = sys_module mac_admin mac_override
lxc.pivotdir = lxc_putold

# uncomment the next line to run the container unconfined:
#lxc.aa_profile = unconfined

lxc.cgroup.devices.deny = a
# Allow any mknod (but not using the node)
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
#lxc.cgroup.devices.allow = c 4:0 rwm
#lxc.cgroup.devices.allow = c 4:1 rwm
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# rtc
lxc.cgroup.devices.allow = c 254:0 rwm
#fuse
lxc.cgroup.devices.allow = c 10:229 rwm
#tun
lxc.cgroup.devices.allow = c 10:200 rwm
#full
lxc.cgroup.devices.allow = c 1:7 rwm
#hpet
lxc.cgroup.devices.allow = c 10:228 rwm
#kvm
lxc.cgroup.devices.allow = c 10:232 rwm

然后我将主机 /etc/network/interfaces 更改为:


auto lo
iface lo inet loopback

auto br0
iface br0 inet static
        bridge_ports eth0
        bridge_fd 0
        address 92.281.86.226
        netmask 255.255.255.0
        network 92.281.86.0
        broadcast 92.281.86.255
        gateway 92.281.86.254
        dns-nameservers 213.186.33.99
        dns-search ovh.net

当我尝试命令行配置(“brctl addif”、“ifconfig eth0”等)时,我的远程主机变得无法访问,我必须硬重启它。

我将 /var/lib/lxc/mycontainer/rootfs/etc/network/interfaces 的内容更改为:


auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 179.43.46.233
        netmask 255.255.255.255
        broadcast 178.33.40.233
        gateway 92.281.86.254

mycontainer 需要几分钟才能启动(lxc-start -n mycontainer)。

我尝试更换

        gateway 92.281.86.254
经过 :

        post-up route add 92.281.86.254 dev eth0
        post-up route add default gw 92.281.86.254
        post-down route del 92.281.86.254 dev eth0
        post-down route del default gw 92.281.86.254

我的容器随即启动。

但是无论我在 /var/lib/lxc/mycontainer/rootfs/etc/network/interfaces 中设置什么配置,我都无法从 mycontainer ping 到任何 IP(包括主机的):


ubuntu@mycontainer:~$ ping 92.281.86.226 
PING 92.281.86.226 (92.281.86.226) 56(84) bytes of data.
^C
--- 92.281.86.226 ping statistics ---
6 packets transmitted, 0 received, 100% packet loss, time 5031ms

并且我的主机无法 ping 通容器:


root@host:~# ping 179.43.46.233
PING 179.43.46.233 (179.43.46.233) 56(84) bytes of data.
^C
--- 179.43.46.233 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 4000ms

我的容器的ifconfig:


ubuntu@mycontainer:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr 02:00:00:86:5b:11  
          inet addr:179.43.46.233  Bcast:255.255.255.255  Mask:0.0.0.0
          inet6 addr: fe80::ff:fe79:5a31/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:64 errors:0 dropped:6 overruns:0 frame:0
          TX packets:54 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4070 (4.0 KB)  TX bytes:4168 (4.1 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2496 (2.4 KB)  TX bytes:2496 (2.4 KB)

我的主机的 ifconfig:


root@host:~# ifconfig
br0       Link encap:Ethernet  HWaddr 4c:72:b9:43:65:2b  
          inet addr:92.281.86.226  Bcast:91.121.67.255  Mask:255.255.255.0
          inet6 addr: fe80::4e72:b9ff:fe43:652b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1453 errors:0 dropped:18 overruns:0 frame:0
          TX packets:1630 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:145125 (145.1 KB)  TX bytes:299943 (299.9 KB)

eth0      Link encap:Ethernet  HWaddr 4c:72:b9:43:65:2b  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3178 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1637 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:298263 (298.2 KB)  TX bytes:309167 (309.1 KB)
          Interrupt:20 Memory:fe500000-fe520000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:300 (300.0 B)  TX bytes:300 (300.0 B)

vethtest  Link encap:Ethernet  HWaddr fe:0d:7f:3e:70:88  
          inet6 addr: fe80::fc0d:7fff:fe3e:7088/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:54 errors:0 dropped:0 overruns:0 frame:0
          TX packets:67 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4168 (4.1 KB)  TX bytes:4250 (4.2 KB)

virbr0    Link encap:Ethernet  HWaddr de:49:c5:66:cf:84  
          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

我已禁用 lxcbr0(/etc/default/lxc 中的 USE_LXC_BRIDGE="false")。


root@host:~# brctl show
bridge name     bridge id               STP enabled     interfaces                                                                                                 
br0             8000.4c72b943652b       no              eth0                                                                                                       
                                                        vethtest        

我已在托管服务提供商 (OVH) 配置面板中将 IP 179.43.46.233 配置为指向 02:00:00:86:5b:11。
(本文中的 IP 不是真实的。)

感谢您阅读这个长问题!:-)

维亚内

答案1

使更改永久生效的更好方法是使用 sysctl 而不是直接写入 /proc,因为这是在运行时配置内核参数的标准方法,以便它们在下次启动时正确设置:

# cat >> /etc/sysctl.d/99-bridge-nf-dont-pass.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-filter-vlan-tagged = 0
EOF
# service procps start

至于您更新中问题的答案......

bridge-netfilter (或 bridge-nf)是 IPv4/IPv6/ARP 数据包(甚至在 802.1Q VLAN 或 PPPoE 报头中)的一个非常简单的桥梁,它提供了状态透明防火墙的功能,但更高级的功能,如透明 IP NAT,是通过将这些数据包传递给 arptables/iptables 进行进一步处理来提供的——然而,即使不需要 arptables/iptables 的更高级功能,在内核模块中仍然默认打开将数据包传递给这些程序,并且必须使用 sysctl 明确关闭。

他们来这里干什么?这些内核配置选项用于将数据包传递(1)或不传递(0)到 arptables/iptables,如bridge-nf 常见问题解答

As of kernel version 2.6.1, there are three sysctl entries for bridge-nf behavioral control (they can be found under /proc/sys/net/bridge/):
bridge-nf-call-arptables - pass (1) or don't pass (0) bridged ARP traffic to arptables' FORWARD chain.
bridge-nf-call-iptables - pass (1) or don't pass (0) bridged IPv4 traffic to iptables' chains.
bridge-nf-call-ip6tables - pass (1) or don't pass (0) bridged IPv6 traffic to ip6tables' chains.
bridge-nf-filter-vlan-tagged - pass (1) or don't pass (0) bridged vlan-tagged ARP/IP traffic to arptables/iptables.

禁用所有 bridge-nf-* 是否安全?是的,这样做不仅安全,而且建议发行版默认关闭该功能帮助人们避免混淆对于您遇到的问题类型:

实际上,这可能会导致严重的混乱,有人创建了网桥,却发现有些流量没有通过网桥转发。由于 IP 防火墙规则应用于网桥上的帧是意料之外的事情,因此可能需要相当长的时间才能弄清楚发生了什么。

提高安全性

我仍然认为桥接的风险更高,尤其是在虚拟化的情况下。考虑一下这样的场景:一台主机上有两个虚拟机,每个虚拟机都有一个专用的桥接器,目的是让它们都不知道对方的流量。

由于 conntrack 作为桥接的一部分运行,流量现在可以跨越,这是一个严重的安全漏洞。

更新:2015 年 5 月

如果您运行的内核版本早于 3.18,那么您可能会受到默认启用桥接过滤这一旧行为的影响;如果您的内核版本高于 3.18,那么如果您已加载桥接模块且未禁用桥接过滤,您仍会受到此行为的影响。请参阅:

https://bugzilla.redhat.com/show_bug.cgi?id=634736#c44

经过这么多年一直要求将桥接过滤的默认设置“禁用”,但这一改变遭到了内核维护人员的拒绝,现在过滤已被移至一个单独的模块,该模块在桥接模块加载时不会(默认情况下)加载,从而有效地将默认设置“禁用”。耶!

思考这是从 3.17 版开始的内核(它肯定在内核 3.18.7-200.fc21 中,并且似乎在 git 中标签“v3.17-rc4”之前)

答案2

我在 Debian Wheezy 虚拟机管理程序上运行了类似的设置。我不必修改容器根文件系统中的 /etc/network/interfaces;在 LXC 的配置中配置 lxc.network.* 就足够了。

无论您是否运行容器,您都应该能够使桥接正常工作。我在主机上的 /etc/network/interfaces 中的 br0 下配置了以下设置:

% grep bridge /etc/network/interfaces
  bridge_ports eth0
  bridge_fd 0
  bridge_stp off
  bridge_waitport 0
  bridge_maxwait 0

配置此项并将我的 IP 地址配置从 eth0 移动到 br0 后,sudo service networking restart透明地重新配置了主机上的接口,而无需删除我的 SSH 会话。

完成后,尝试删除 /etc/network/interfaces 中的“eth0”配置并重新启动容器。

相关内容