使用 nftables 在 LXC 容器中访问互联网

使用 nftables 在 LXC 容器中访问互联网

我目前正在尝试使用 nftables 为 LXC 容器提供互联网访问权限,但我似乎没有做对。

设置如下:主机有一个 WAN 接口 (enp1s0) 和一个网桥 (lxcbrd)。我没有使用lxc-net,而是我自己制作的一个桥接器,如下所示:

allow-hotplug enp1s0
iface enp1s0 inet dhcp

auto lxcbrd
iface lxcbrd inet static
        bridge_ports none
        bridge_fd 0
        bridge_maxwait 0
        address 10.0.0.254
        netmask 255.255.255.0

LXC 容器配置为使用 lxcbrd...

lxc.network.type = veth
lxc.network.link = lxcbrd
lxc.network.ipv4 = 10.0.0.1/24
lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:98:34:26
lxc.network.ipv4.gateway = auto

...看来它在某种程度上取得了成功:

2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [REDACTED] brd ff:ff:ff:ff:ff:ff
    inet [REDACTED] brd [REDACTED] scope global enp1s0
       valid_lft forever preferred_lft forever
    inet6 [REDACTED] scope link 
       valid_lft forever preferred_lft forever
3: lxcbrd: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fe:5f:9a:9b:75:a4 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.254/24 brd 10.0.0.255 scope global lxcbrd
       valid_lft forever preferred_lft forever
    inet6 fe80::6414:77ff:fe2d:6699/64 scope link 
       valid_lft forever preferred_lft forever
5: vethPPYOVI@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master lxcbrd state UP group default qlen 1000
    link/ether fe:5f:9a:9b:75:a4 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::fc5f:9aff:fe9b:75a4/64 scope link 
       valid_lft forever preferred_lft forever

在主机上,nftables 配置为 nat 并转发:

table ip nat {
        chain prerouting {
                type nat hook prerouting priority 0; policy accept;
        }

        chain postrouting {
                type nat hook postrouting priority 0; policy accept;
                oifname "enp1s0" masquerade
        }
}
table inet filter {
        chain input {
                type filter hook input priority 0; policy drop;
                ct state { established, related} accept comment "accept all traffic originated from us"
                ct state invalid drop comment "drop invalid packets"
                iif "lo" accept comment "accept all loopback traffic"
                icmp type { router-advertisement, destination-unreachable, parameter-problem, time-exceeded} accept comment "ICMP"
                icmpv6 type { nd-neighbor-solicit, time-exceeded, destination-unreachable, packet-too-big, nd-neighbor-advert, parameter-problem, nd-router-advert} accept comment "ICMPv6"
                tcp dport 2222 ct state new accept comment "ssh"
                udp dport 60000-61000 ct state new accept comment "mosh"
        }

        chain forward {
                type filter hook forward priority 0; policy accept;
                iifname "lxcbrd" oifname "enp1s0" accept
                iifname "enp1s0" oifname "lxcbrd" accept
        }

        chain output {
                type filter hook output priority 0; policy accept;
        }
}

从容器内部:

6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:98:34:26 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.0.1/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe98:3426/64 scope link 
       valid_lft forever preferred_lft forever

但是,我无法从容器内部访问任何互联网。从主机上,我可以毫无问题地对容器执行 ping 操作。

更新:使用此配置,我什至无法 ping 网关(即 10.0.0.254),但我可以 ping 同一子网上的另一个容器(10.0.0.0/24)。如果我将 nftables chain inet 过滤器输入设置为策略接受,我可以 ping 网关,但不能 ping 通子网外的 IP(例如 8.8.8.8);考虑到应该允许所有 icmp 流量的规则,我不完全确定为什么它的行为如此。

UPDATE2:在echo 1 > /proc/sys/net/ipv4/ip_forward(我确信我已经设置了这个/etc/sysctl.conf......显然没有)之后,我能够 ping WAN IP(例如 8.8.8.8),并在手动将 Google DNS 服务器添加到 /etc/ 后解析 DNS解决.conf。但是,如果 nftables chain inet 过滤器输入设置为策略丢弃,我无法 ping 网关(即桥接接口的地址 (10.0.0.254))。

有人发现我的配置有严重错误吗?

谢谢您的帮助 !

相关内容