现象
宿主机上的iptables规则无法限制docker容器映射出的端口(--net=host除外),就算在 filter 表的 INPUT 链设置了DROP外界仍然可以访问。
外界访问容器端口的数据流向
# 外界访问容器端口的数据流向(docker run 为(-p)端口映射方式)
raw:PREROUTING -> nat:PREROUTING(DOCKER链转发到容器) -> filter:FORWARD(DOCKER-USER链位于此处做访问控制) -> security:FORWARD -> nat:POSTROUTINGDOCKER-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/0DOCKER-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/0DOCKER链
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