我的网络被隔离成几个不同的 VLAN,但我对如何隔离在自定义桥接网络内运行的一些 docker 容器感到有点困惑。为了简单起见,假设网络如下所示,并且有两个 VLAN(受信任流量未标记,不受信任流量在 VLAN 10 上)。未标记流量在 192.168.x.0/24 子网上,VLAN 10 在 10.xx0/24 子网上。
我在 Unraid 上运行 docker,并将其设置为允许 VLAN,并且它在未标记子网和 VLAN 10 子网上都获得一个 IP。Unraid 的配置使得只有 docker 可以在 VLAN 10 上访问,并且一些容器在自定义桥接网络 (10.99.99.0/24) 中运行,一切都以单向方式运行。将端口映射到容器时,我使用 <VLAN 10 IP>:Port,以便端口只能通过 VLAN 10 IP 访问。这样我就可以让一些容器在 docker 网络内运行,这些容器完全在该网络内部,外部无法访问。
我遇到的问题是容器本身可以与未标记的网络进行通信。我认为这是有道理的,因为主机有到未标记网络的路由,而 docker 流量没有标记 VLAN ID。
我尝试创建一个 iptables 规则来丢弃 docker 10.99.99.0/24 接口和 br0 之间的流量
iptables -A FORWARD -i br-<MAC> -o br0 -j DROP
但这似乎不起作用,交通仍然可以通过。
如何为此设置添加出站隔离?(即我只想允许来自此 docker 网络的流量通过 br.10 接口传出)
我不想只使用 MACVLAN 网络并将设备放在 VLAN 10 上,因为它们是容器上的端口,我不希望其他设备可以访问它们,而且有些容器我根本不想在该子网上被看到。
理想情况下,最好在主机级别完成所有这些操作,但我能看到的唯一其他选择是在新 VLAN 上创建 MACVLAN 网络并在路由器上应用大量防火墙规则(这有点难以维护,因为我将需要修复容器的 IP 等)
答案1
iptables 规则应该足够了。它需要位于链的顶部FORWARD
;例如:
iptables -A FORWARD -s 10.99.99.0/24 -d 192.168.x.0/24 -j DROP
它需要在顶部链,否则它将成为一个无操作——Docker 添加了一些规则来明确控制ACCEPT
流量。
您也可以将规则添加到DOCKER-USER
链中;这是 Docker 安排在任何 Docker 管理的规则之前调用的链。FORWARD
我本地系统上的链如下所示:
-P FORWARD ACCEPT
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
.
.
.
或者,您可以添加策略路由规则,以便来自容器的流量不会路由到未标记的网络。您的默认路由策略如下所示:
# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
main
运行 时,您会看到以下表格ip route
。您可以添加一条规则,使用备用查找来查找来自容器的流量:
ip rule add priority 1000 from 10.99.99.0/24 lookup 1000
这应该导致:
# ip rule show
0: from all lookup local
1000: from 10.99.99.0/24 lookup 1000
32766: from all lookup main
32767: from all lookup default
然后向表1000中添加路由条目:
ip route add table 1000 default via 10.x.x.1
现在来自容器的连接将只有默认路由,并且只有 10.xx1 处的路由器提供了适当的路由时才能够访问未标记的网络。