docker 容器安装会破坏该计算机上现有桥接口后面的计算机的 DHCP

docker 容器安装会破坏该计算机上现有桥接口后面的计算机的 DHCP

我的初始状态是这样的:

  • 带有住宅网关的“普通”家庭网络,该网关将 DHCP 地址分发给子网 192.168.15.0/24 上的有线和无线计算机的组合。
  • 混合了 Windows 和 Linux 客户机的 Linux (Ubuntu 18.04.3) 虚拟机主机。此 VM 主机使用单个桥接接口将 VM 来宾接口直接桥接到 192.168.15.x 网络。这里的 eno1 和 ens2 是将 VM 主机连接到主网络并将该桥接域“扩展”到另一个物理交换机的物理以太网端口,而 vnetX 接口是 VM 来宾计算机的接口。
lwobker@lwobker-vms:~$ brctl show 
bridge name     bridge id               STP enabled     interfaces
bridge1         8000.0017b60066e8       no              eno1    # goes to router/gateway
                                                        ens2    # extends the subnet to other machines
                                                        vnet0   # VM guest #1
                                                        vnet1   # VM guest #2
docker0         8000.0242bd3d4632       no
virbr0          8000.52540096aaf5       yes             virbr0-nic

这一切都按照我想要的方式工作,本地有线、无线和 VM 来宾客户端都可以从主 192.168.15.1 res-网关/路由器获取 DHCP 地址,其中一些在 DHCP 服务器端保留/静态,另一些则在 DHCP 服务器端保留/静态。是动态的。无论如何 - 一切都好......直到......

我安装了 Docker。我这样做是为了在容器中运行 Ubiquity/Unifi 无线 AP 控制器软件,这似乎是一个很好/简单的使用容器的用例。然而,在安装 Docker 的过程中的某个地方(我非常确定更准确地说是 Docker 网络更改)破坏了 VM 主机桥接接口后面的任何内容的 DHCP。明确地说:

  • 不在 VM 主机后面的有线和无线客户端仍然通常从 192.168.15.1 接收 DHCP 地址(保留的和动态的)
  • 所有坐着的机器在后面VM 主机桥不再接收 DHCP 地址。这包括 VM 本身上的虚拟机来宾实例,以及通过接口 ens2 物理连接的计算机。
  • 重要的是:IPv6 寻址仍然可以在这个新的 Dockerfied VM 主机后面的机器上运行,并且只要目标是可路由的 v6 地址,这些机器仍然可以成功访问互联网。

我显然是 docker 的新手,并且对 Linux 网络和桥接有很好的掌握,但这超出了我的能力范围。我已经启动了tcpdump几次,我可以看到 DHCP 通过阅读它很可能与 iptables 相关 - 我没有iptables --listdocker 安装之前的输出,但显然添加了一些条目;- )我已经在下面列出了我能说服自己相关的所有内容,并尝试对特别重要的条目进行注释。帮助?!?!!

lwobker@lwobker-vms:~$ brctl showmacs bridge1 | uniq
port no mac addr                is local?       ageing timer
1     18:1d:ea:8a:86:e9       no                49.83
1     44:61:32:d0:43:02       no               117.27
1     44:61:32:fb:4d:7b       no               117.27
1     60:6d:c7:1a:8f:e1       no                 4.47
1     78:f2:9e:90:4c:a1       no                 1.21
1     7c:2e:bd:9c:4a:4a       no                 0.00
1     80:4a:14:ec:5a:ea       no                95.33
1     80:4a:14:f3:d8:8c       no                71.62
1     90:70:65:13:b7:16       no               117.16
1     a0:cc:2b:ff:a4:b4       no                 0.70
1     ac:1f:6b:b3:ad:fa       yes                0.00
1     ac:1f:6b:b7:d2:44       no               286.56
1     b4:fb:e4:d6:e2:35       no                 2.54
1     b8:27:eb:f9:c6:fe       no               117.18
1     d8:31:34:f3:2c:69       no                62.38
1     ec:11:27:58:a8:0d       no                 0.22
2     00:17:b6:00:66:e8       yes                0.00
2     00:30:93:10:05:8e       no                 3.61     >> physical machine behind intf ens2
3     52:54:00:ed:c9:fc       no                 0.67     >> linux VM guest
3     fe:54:00:ed:c9:fc       yes                0.00
4     52:54:00:d9:2d:b0       no                 1.29     >> windows VM guest
4     fe:54:00:d9:2d:b0       yes                0.00

当前 iptables 输出:

lwobker@lwobker-vms:/storage/unifi$ sudo iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps
ACCEPT     udp  --  anywhere             anywhere             multiport dports mdns
ACCEPT     tcp  --  anywhere             anywhere             multiport dports 4000

Chain FORWARD (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
ACCEPT     all  --  192.168.122.0/24     anywhere            
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootpc

Chain DOCKER (1 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            



lwobker@lwobker-vms:/storage/unifi$ docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                 PORTS               NAMES
be342a77a105        jacobalberty/unifi:stable   "/usr/local/bin/dock…"   23 hours ago        Up 5 hours (healthy)                       unifi

桥接器 docker 网络检查的输出...

lwobker@lwobker-vms:/storage/unifi$ docker network inspect 20d74e3d7efc
[
    {
        "Name": "bridge",
        "Id": "20d74e3d7efc41320c054dbd4fde76808a7c0e021e737e22cfceebefacb24b8c",
        "Created": "2019-10-15T12:36:22.059240054-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

VM 主机的 ifconfig 输出...

lwobker@lwobker-vms:~$ ifconfig | egrep -v 'errors|0.0 B|device mem'
bridge1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.15.150  netmask 255.255.255.0  broadcast 192.168.15.255
        ether 00:17:b6:00:66:e8  txqueuelen 1000  (Ethernet)
        RX packets 105730  bytes 73076273 (73.0 MB)
        TX packets 47591  bytes 11607902 (11.6 MB)

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:bd:3d:46:32  txqueuelen 0  (Ethernet)

eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether ac:1f:6b:b3:ad:fa  txqueuelen 1000  (Ethernet)
        RX packets 479110  bytes 451330614 (451.3 MB)
        TX packets 352901  bytes 284906323 (284.9 MB)

eno2: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether ac:1f:6b:b3:ad:fb  txqueuelen 1000  (Ethernet)

eno2:avahi: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 169.254.11.170  netmask 255.255.0.0  broadcast 169.254.255.255
        ether ac:1f:6b:b3:ad:fb  txqueuelen 1000  (Ethernet)

ens2: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 00:17:b6:00:66:e8  txqueuelen 1000  (Ethernet)
        RX packets 375663  bytes 281196261 (281.1 MB)
        TX packets 292663  bytes 270964344 (270.9 MB)

ens2:avahi: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 169.254.8.164  netmask 255.255.0.0  broadcast 169.254.255.255
        ether 00:17:b6:00:66:e8  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 92697  bytes 34802204 (34.8 MB)
        TX packets 92697  bytes 34802204 (34.8 MB)

virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether 52:54:00:96:aa:f5  txqueuelen 1000  (Ethernet)

virbr0-nic: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 52:54:00:96:aa:f5  txqueuelen 1000  (Ethernet)

vnet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether fe:54:00:ed:c9:fc  txqueuelen 1000  (Ethernet)
        RX packets 4563  bytes 509949 (509.9 KB)
        TX packets 28463  bytes 2796658 (2.7 MB)

vnet1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether fe:54:00:d9:2d:b0  txqueuelen 1000  (Ethernet)
        RX packets 50067  bytes 5253268 (5.2 MB)
        TX packets 82339  bytes 105281318 (105.2 MB)

vnet0:avahi: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.12.44  netmask 255.255.0.0  broadcast 169.254.255.255
        ether fe:54:00:ed:c9:fc  txqueuelen 1000  (Ethernet)

vnet1:avahi: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.8.4  netmask 255.255.0.0  broadcast 169.254.255.255
        ether fe:54:00:d9:2d:b0  txqueuelen 1000  (Ethernet)

答案1

快速修复:

iptables -t filter -P FORWARD ACCEPT

更好的修复:

iptables -A FORWARD -p udp --sport 68 --dport 67 -m conntrack --ctstate NEW -j ACCEPT

答案2

我注册只是为了对所提供的快速和详细的修复表示“谢谢”。我没有足够的声誉来直接评论他的回复。感谢@Stuart Cardall 在无数个小时的调试和拉扯我的头发后帮助我。

我确实必须添加一些额外的发现。第一个建议的命令不仅是快速的,而且是临时修复。如果在 docker 启动之前应用该规则,docker 启动后会立即再次将其切换为 DENY。

对于第二个命令,这是我需要的一个命令,但我还需要一个在另一个方向转发数据包的命令。所以最后我用了

iptables -A FORWARD -p udp --sport 68 --dport 67 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -p udp --sport 67 --dport 68 -m conntrack --ctstate NEW -j ACCEPT

有了这些规则,以及任何类型的 iptables 持久性(ArchLinux 上的 /etc/iptables/iptables.rules),我就能够让我的 VPN 客户端从网络路由器获取地址。

相关内容