【发布时间】:2019-02-21 05:03:03
【问题描述】:
Iptables 规则是 notoriously difficult 在 Docker 在主机上运行时设置,我认为我在这篇精彩的博文中找到了明确的解决方案:https://unrouted.io/2017/08/15/docker-firewall/
这篇博文中描述的配置已经为我服务了很长时间,但我现在遇到了一个以前从未遇到过的问题。
我正在运行一个 docker 容器,该容器在主机的 465 端口上公开了一项服务。 465 端口映射到容器中的 25 端口。以下是模拟此类服务的方法:
$ docker run --rm -it -p 465:25 python:3.6 python3 -m http.server 25
我的问题是我无法从外部访问服务器上的 465 端口:
$ curl mydomain.com:465
curl: (7) Failed to connect to mydomain.com port 465: No route to host
然而,有趣的部分来了,如果主机上的端口映射到容器中的相同端口,我确实可以访问该服务。也就是说,当我在主机上运行时:
$ docker run --rm -it -p 465:465 python:3.6 python3 -m http.server 465
然后我可以从外部访问服务:
$ curl mydomain.com:465
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org...
这整个问题是由于我的 iptables 定义:我知道,因为当我刷新 iptables 规则时,我确实设法从外部访问服务,无论端口映射如何。
这是我的 iptable 规则:
*filter
# Source: https://unrouted.io/2017/08/15/docker-firewall/
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:FILTERS - [0:0]
:DOCKER-USER - [0:0]
-F INPUT
-F DOCKER-USER
-F FILTERS
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT
-A INPUT -p icmp --icmp-type any -j ACCEPT
-A INPUT -j FILTERS
-A DOCKER-USER -i eth0 -j FILTERS
-A FILTERS -m state --state ESTABLISHED,RELATED -j ACCEPT
-A FILTERS -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A FILTERS -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A FILTERS -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A FILTERS -m state --state NEW -m tcp -p tcp --dport 465 -j ACCEPT
-A FILTERS -j REJECT --reject-with icmp-host-prohibited
COMMIT
无论端口映射如何,我应该如何修改我的 iptables 以便我可以从外部访问我的容器?
编辑:
以下是失败场景中完整的 iptables 规则(465:25 映射):
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
REJECT all -- loopback/8 anywhere reject-with icmp-port-unreachable
ACCEPT icmp -- anywhere anywhere icmp any
FILTERS all -- anywhere anywhere
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (3 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.19.0.4 tcp dpt:3000
ACCEPT tcp -- anywhere 172.17.0.3 tcp dpt:smtp
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (3 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
FILTERS all -- anywhere anywhere
Chain FILTERS (2 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:https
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:urd
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
【问题讨论】: