社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

Docker 火了!外部网络可直接访问映射到 127.0.0.1 的服务。。。

方志朋 • 2 年前 • 378 次点击  

迎关注方志朋的博客,回复”666“获面试宝典

来源:云原生实验室


这两天 Hacker News 上面有一个贴子火了,这是一封发给 Docker 安全团队的邮件,主要讲的是 Docker 有一个非常离谱的安全隐患。


即使你通过像 -p 127.0.0.1:80:80这样的参数将端口暴露到回环地址,外部仍然可以访问该服务,怎么回事呢?


原因其实很简单,Docker 添加了这样一条 Iptables 规则:
🐳  → iptables -nvL DOCKERChain DOCKER (2 references) pkts bytes target prot opt in       out     source    destination    0


    
 0     ACCEPT tcp  --  !docker0 docker0 0.0.0.0/0 172.17.0.2  tcp dpt:80

只要外部攻击者通过这台主机将流量发送到 172.17.0.2:80,就会匹配这条规则并成功访问容器中的服务,127.0.0.1 并没有什么卵用。


尴尬的是,选择将端口映射到 127.0.0.1 的用户基本上都是觉得这样很安全,以至于他们不再想采取进一步的安全措施。现在问题来了,映射到 127.0.0.1 不能说是非常安全吧,只能说是与安全毫不相干。。。


# 概念验证


下面通过一个例子来验证。


在 A 机器上运行一个 PostgreSQL 容器,并将端口映射到 127.0.0.1。
# IP: 192.168.0.100🐳  → docker run -e POSTGRES_PASSWORD=password -p 127.0.0.1:5432:5432 postgres
同一个局域网中的 B 机器添加路由表,将所有访问 172.16.0.0/12 的流量指向 A 机器。
# IP: 192.168.0.200🐳  → ip route add 172.16.0.0/12


    
 via 192.168.0.100
在 B 机器中扫描 A 机器的端口。
🐳  → nmap -p5432 -Pn --open 172.16.0.0/12Starting Nmap 7.92 ( https://nmap.org ) at 2021-11-05 15:00 CDTNmap scan report for 172.17.0.2Host is up (0.00047s latency).
PORT STATE SERVICE5432/tcp open postgresql
在 B 机器中直接连接 PostgreSQL。



    
🐳  → psql -h 172.17.0.2 -U postgresPassword for user postgres:


# 解决方案


事实上不仅仅是 127.0.0.1,你将容器端口映射到主机的任何一个地址,外部都可以访问到,这就离了大谱了!


邮件作者给 Docker 团队提出了一个解决方案,希望能优化 Docker 的 iptables 规则:


首先要严格限制允许访问容器端口的源地址和网络接口,例如 docker run -p 127.0.0.1:5432:5432 的原 iptables 规则如下:
Chain DOCKER (2 references) pkts bytes target prot opt in       out     source    destination    0 0     ACCEPT tcp  --  !docker0 docker0 


    
0.0.0.0/0 172.17.0.2  tcp dpt:5432

改进后的 iptables 规则如下:

Chain DOCKER (2 references) pkts bytes target prot opt in out     source      destination    0 0     ACCEPT tcp  --  lo docker0 127.0.0.1/8 172.17.0.2 tcp dpt:5432

同理,如果主机的地址为 192.168.0.100,掩码为 24,那么 docker run -p 192.168.0.100:5432:5432 的 iptables 规则就应该是:

Chain DOCKER (2 references) pkts bytes target prot opt in   out     source         destination    0 0     ACCEPT tcp  --  eth0 docker0 192.168.0.0/24 172.17.0.2 tcp dpt:5432
最后要修改默认行为,如果使用 -p 参数时没有指定任何 IP 地址,就默认映射到 127.0.0.1。

虽然评论区也有很多人给出了添加 iptables 规则来进行限制的方案,但这是不现实的,目前全世界有成千上万的用户在使用 -p 参数将容器端口映射到 127.0.0.1,攻击者估计早就发现了这个漏洞,我们不能期望用户自己添加 iptables 规则来限制外部访问,最靠谱的方式还是等 Docker 官方修复这个 bug 然后升级吧。


# 引用链接

Hacker News 上面有一个贴子: https://news.ycombinator.com/item?id=31839936


热门内容:



    
最近面试BAT,整理一份面试资料Java面试BAT通关手册,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/137516
 
378 次点击