先说一下我这边的软件运行环境,主机上既有本地运行的程序,也有基于 docker 运行的程序。最近发现基于 docker 的应用端口有外部攻击痕迹,于是准备在 iptables 中写策略封端口,结果发现不生效。
原生的 iptables 策略如下:
bash# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-1 all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 192.168.250.4 tcp dpt:63790
ACCEPT tcp -- 0.0.0.0/0 192.168.250.4 tcp dpt:33062
ACCEPT tcp -- 0.0.0.0/0 192.168.250.4 tcp dpt:33061
ACCEPT tcp -- 0.0.0.0/0 192.168.250.5 tcp dpt:2222
ACCEPT tcp -- 0.0.0.0/0 192.168.250.8 tcp dpt:80
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
本打算在 INPUT 链中直接封掉 80 端口,结果发现封不掉:
bash# iptables -I INPUT -p tcp -m tcp --dport 80 -j DROP
bash# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
在网页上测试 80 端口,服务仍然可以访问。此时发现在 INPUT 链中写拒绝策略对 docker 应用不起作用。
同时通过 netstat 查看会话信息也查不到任何关于 80 端口的外部连接信息:
bash# netstat -an| grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 :::80 :::* LISTEN
认真思考一下可以理解为 docker 容器是一个隔离的“虚拟机”,宿主机的会话信息与容器的会话信息是隔离的。所以在宿主机上无法直接查看容器的会话信息。
同样 INPUT 链只对宿主机的应用起作用,如果要写容器的 iptables 策略,可以 DOCKER 链中去写。
在 DOCKER 链中测试了 DROP 策略后,测试结果显示 DROP 策略是生效的。
bash# iptables -I DOCKER -s 10.20.94.10 -j DROP
bash# iptables -nL DOCKER
Chain DOCKER (2 references)
target prot opt source destination
DROP all -- 10.20.94.10 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 192.168.250.4 tcp dpt:63790
ACCEPT tcp -- 0.0.0.0/0 192.168.250.4 tcp dpt:33062
ACCEPT tcp -- 0.0.0.0/0 192.168.250.4 tcp dpt:33061
ACCEPT tcp -- 0.0.0.0/0 192.168.250.5 tcp dpt:2222
ACCEPT tcp -- 0.0.0.0/0 192.168.250.8 tcp dpt:80
总结:
宿主机的 iptables 策略与 docker 容器的 iptables 策略是不通用的。我们无法在 INPUT 链上防护 docker 容器的端口。
如果要阻止外部 IP 访问 docker 应用,需要要 DOCKER 链上写防护策略,而 INPUT 链只对宿主机应用生效。
全文完。
如果转发本文,文末务必注明:“转自微信公众号:生有可恋”。
原文始发于微信公众号(生有可恋):docker 映射出来的端口如何写 iptables 规则
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论