社区所有版块导航
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 的服务

程序猿 • 1 年前 • 173 次点击  

来自公众号:云原生实验室

作者:米开朗基杨

这两天 Hacker News 上面有一个贴子[1]火了,这是一封发给 Docker 安全团队的邮件,主要讲的是 Docker 有一个非常离谱的安全隐患。即使你通过像 -p 127.0.0.1:80:80 这样的参数将端口暴露到回环地址,外部仍然可以访问该服务,怎么回事呢?

原因其实很简单,Docker 添加了这样一条 Iptables 规则:

🐳  → iptables -nvL DOCKER
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: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/12
Starting Nmap 7.92 ( https://nmap.org ) at 2021-11-05 15:00 CDT
Nmap scan report for 172.17.0.2
Host is up (0.00047s latency).

PORT     STATE SERVICE
5432/tcp open  postgresql

④ 在 B 机器中直接连接 PostgreSQL。

🐳  → psql -h 172.17.0.2 -U postgres
Password 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 然后升级吧。

引用链接

[1]

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


--- EOF ---


推荐↓↓↓
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/137192
 
173 次点击