Docker and iptables

预计阅读时间:4分钟

在 Linux 上,Docker 操纵iptables规则来提供网络隔离. 虽然这是一个实现细节,并且您不应该修改 Docker 插入到您的iptables策略中的规则,但如果您想要拥有自己的策略以及由 Docker 管理的策略,它确实会对您需要做的事情产生一些影响.

如果您在暴露于 Internet 的主机上运行 Docker,您可能希望有适当的 iptables 策略来防止未经授权访问在您的主机上运行的容器或其他服务. 本页介绍了如何实现这一目标,以及您需要注意哪些注意事项.

Add iptables policies before Docker’s rules

Docker 安装了两个名为DOCKER-USERDOCKER的自定义 iptables 链,它确保传入的数据包始终首先由这两个链检查.

Docker 的所有iptables规则都添加到DOCKER链中. 不要手动操作此链. 如果您需要添加在 Docker 规则之前加载的规则,请将它们添加到DOCKER-USER链中. 这些规则在 Docker 自动创建的任何规则之前应用.

添加到FORWARD链的规则(手动或通过另一个基于 iptables 的防火墙)在这些链之后进行评估. 这意味着如果您通过 Docker 公开一个端口,无论您的防火墙配置了什么规则,该端口都会被公开. 如果您希望即使端口通过 Docker 暴露也能应用这些规则,则必须将这些规则添加到DOCKER-USER链中.

Restrict connections to the Docker host

默认情况下,允许所有外部源 IP 连接到 Docker 主机. 要仅允许特定 IP 或网络访问容器,请在DOCKER-USER过滤器链的顶部插入否定规则. 例如,以下规则限制来自除192.168.1.1之外的所有 IP 地址的外部访问:

$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP

请注意,您需要更改ext_if以与主机的实际外部接口相对应. 您可以改为允许来自源子网的连接. 以下规则仅允许从子网192.168.1.0/24访问:

$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP

最后,您可以使用--src-range指定要接受的 IP 地址范围(请记住,在使用--src-range--dst-range时还要添加-m iprange iprange):

$ iptables -I DOCKER-USER -m iprange -i ext_if ! --src-range 192.168.1.1-192.168.1.3 -j DROP

您可以将-s--src-range-d--dst-range结合使用来控制源和目标. 例如,如果 Docker 守护程序同时侦听192.168.1.9910.1.2.3 ,您可以制定特定于10.1.2.3的规则并让192.168.1.99保持打开状态.

iptables很复杂,更复杂的规则超出了本主题的范围. 有关更多信息,请参阅Netfilter.org HOWTO .

Docker on a router

Docker 还将FORWARD链的策略设置为DROP . 如果您的 Docker 主机还充当路由器,这将导致该路由器不再转发任何流量. 如果您希望您的系统继续作为路由器运行,您可以向DOCKER-USER链添加显式ACCEPT规则以允许它:

$ iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT

Prevent Docker from manipulating iptables

可以在 Docker 引擎的配置文件/etc/docker/daemon.json中将iptables键设置为false ,但此选项不适合大多数用户. 完全阻止 Docker 创建iptables规则是不可能的,事后创建它们非常复杂,超出了这些说明的范围. 将iptables设置为false很可能会破坏 Docker 引擎的容器网络.

对于希望将 Docker 运行时构建到其他应用程序中的系统集成商,请探索moby项目.

Setting the default bind address for containers

默认情况下,Docker 守护进程会暴露0.0.0.0地址上的端口,即主机上的任何地址. 如果您想更改该行为以仅公开内部 IP 地址上的端口,您可以使用--ip选项指定不同的 IP 地址. 但是,设置--ip只会更改默认值,它不会将服务限制到该 IP.

Integration with Firewalld

如果您在系统上运行 Docker 版本 20.10.0 或更高版本并启用了--iptablesfirewalld ,Docker 会自动创建一个名为dockerfirewalld区域,并将它创建的所有网络接口(例如docker0 )插入docker区域以允许无缝网络.

考虑运行以下firewalld命令以从区域中删除 docker 接口.

# Please substitute the appropriate zone and docker interface
$ firewall-cmd --zone=trusted --remove-interface=docker0 --permanent
$ firewall-cmd --reload

重新启动dockerd守护程序会将接口插入docker区域.

network, iptables

by  icopy.site