使用Docker时宿主机iptables失效问题

现象

宿主机上的iptables规则无法限制docker容器映射出的端口(--net=host除外),就算在 filter 表的 INPUT 链设置了DROP外界仍然可以访问。

外界访问容器端口的数据流向

# 外界访问容器端口的数据流向(docker run 为(-p)端口映射方式)
raw:PREROUTING -> nat:PREROUTING(DOCKER链转发到容器) -> filter:FORWARD(DOCKER-USER链位于此处做访问控制) -> security:FORWARD -> nat:POSTROUTING

DOCKER-USER链

如果没有禁用Docker自动管理iptables规则,一般DOCKER-USER链会被添加到FORWARD链中。

filter 表 DOCKER-USER 链为Docker定义给用户用来添加自定义规则来限制访问容器端口的策略。

# iptables -t filter -L FORWARD -n | grep DOCKER
DOCKER-USER  0    --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-1  0    --  0.0.0.0/0            0.0.0.0/0

DOCKER-ISOLATION-STAGE链

filter 表 DOCKER-ISOLATION-STAGE 链用来实现Docker多network中的容器互相隔离,不能进行互通

# iptables -t filter -L DOCKER-ISOLATION-STAGE-1 -n
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  0    --  0.0.0.0/0            0.0.0.0/0
RETURN     0    --  0.0.0.0/0            0.0.0.0/0

# iptables -t filter -L DOCKER-ISOLATION-STAGE-2 -n
Chain DOCKER-ISOLATION-STAGE-2 (8 references)
target     prot opt source               destination
DROP       0    --  0.0.0.0/0            0.0.0.0/0
RETURN     0    --  0.0.0.0/0            0.0.0.0/0

DOCKER链

nat 表 DOCKER 链用来实现用户配置的端口映射策略,如192.168.1.2:80映射到容器80端口

# iptables -t nat -L DOCKER  -n
Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     0    --  0.0.0.0/0            0.0.0.0/0
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:3000 to:10.0.0.21:3000
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8096 to:172.17.0.3:8096
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:10051 to:10.0.0.100:10051
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:5244 to:172.17.0.4:5244
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:10.0.0.101:8080
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:3306 to:10.0.0.10:3306
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8090 to:172.22.0.3:8090
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:2283 to:172.18.0.5:2283
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:12001 to:172.23.0.4:443
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:5800 to:172.17.0.2:5800
DNAT       6    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:5900 to:172.17.0.2:5900

解决方法

在filter 表中的DOCKER-USER链中加配置即可(添加规则时需要以容器的IP和端口为准,而不是映射到宿主机的端口)

# iptables -t filter -L DOCKER-USER -n
Chain DOCKER-USER (1 references)
target     prot opt source               destination
ACCEPT     6    --  0.0.0.0/0            172.0.0.0/8          tcp dpt:443
ACCEPT     0    --  192.168.122.0/24     0.0.0.0/0
ACCEPT     0    --  172.19.0.0/24        0.0.0.0/0
ACCEPT     0    --  172.18.0.0/24        0.0.0.0/0
ACCEPT     0    --  10.0.0.0/16          0.0.0.0/0
ACCEPT     0    --  127.0.0.0/24         0.0.0.0/0
ACCEPT     0    --  172.17.0.0/24        0.0.0.0/0
ACCEPT     0    --  10.11.0.0/24         0.0.0.0/0
DROP       0    --  0.0.0.0/0            0.0.0.0/0            state NEW /* DOCKER IN AND OUT INTERNET */
RETURN     0    --  0.0.0.0/0            0.0.0.0/0

根目录扩容 2025-07-30
Linux时间设置 2025-07-29

评论区