我正在使用 Docker 0.7.0 在 RedHat Enterprise Linux 6.5 上创建容器。当防火墙关闭时,容器可以与外界通信,但当防火墙打开时,容器无法从外部访问。
这就是我运行docker并将端口从主机映射到容器的方式
$ docker run -i -t -p 3838:3838 shiny "shiny-server"
如果没有防火墙,我可以从外部网络访问在端口 3838 上运行的容器内的 Node.js 服务器http://servername:3838
,但防火墙打开后则无法访问。
这些是我的默认防火墙规则 –
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
我尝试通过添加如下规则来打开端口 3838,但没有成功
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3838 -j ACCEPT
Docker 正在主机上创建虚拟 NAT,我感觉防火墙以某种方式阻止了从 eth0 到 docker 0 的数据包转发
我需要帮助配置 iptables,以便可以从外部网络访问 docker 容器,而无需关闭整个防火墙。
这是 $ifconfig 的输出(我屏蔽了服务器 IP)
docker0 Link encap:Ethernet HWaddr 00:00:00:00:00:00
inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::87d:8dff:fed0:f16d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:408321 errors:0 dropped:0 overruns:0 frame:0
TX packets:681809 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:126511933 (120.6 MiB) TX bytes:924200959 (881.3 MiB)
eth0 Link encap:Ethernet HWaddr 00:25:64:A8:5B:8F
inet addr:XXX.XXX.XXX.XXX Bcast:XXX.XXX.XXX.XXX Mask:255.255.240.0
inet6 addr: XXXX::XXX:XXXX:XXXX:XXXX/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:29786186 errors:0 dropped:0 overruns:0 frame:0
TX packets:1137982 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4209047011 (3.9 GiB) TX bytes:234657696 (223.7 MiB)
Interrupt:17
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:8444 errors:0 dropped:0 overruns:0 frame:0
TX packets:8444 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4701771 (4.4 MiB) TX bytes:4701771 (4.4 MiB)
$docker version 的输出:
Client version: 0.7.0
Go version (client): go1.1.2
Git commit (client): 0ff9bc1/0.7.0
Server version: 0.7.0
Git commit (server): 0ff9bc1/0.7.0
Go version (server): go1.1.2
Last stable version: 0.7.2, please update docker
$docker info 的输出:
Containers: 321
Images: 278
Driver: devicemapper
Pool Name: docker-8:17-13239310-pool
Data file: /var/lib/docker/devicemapper/devicemapper/data
Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: 56464.5 Mb
Data Space Total: 102400.0 Mb
Metadata Space Used: 59.5 Mb
Metadata Space Total: 2048.0 Mb
答案1
我相信您还必须允许数据包进入 FORWARD 链。您还需要确保添加的 ALLOW 规则位于 REJECT 规则之前,因为 iptables 以先匹配即获胜为基础工作。
答案2
我遇到了类似的问题,而解决方案是缺少 Masquarading - 这也无法解释为什么它在没有任何过滤规则的情况下也能工作。
您尝试添加以下规则怎么样:
*filter
[...]
-A FORWARD -d 172.17.42.0/16 -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 172.17.42.0/16 -i docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -o docker0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i docker0 -j REJECT --reject-with icmp-port-unreachable
*nat
[...]
-A POSTROUTING -s 172.17.42.0/16 ! -d 172.17.42.0/16 -p tcp -j MASQUERADE --to-ports 1016-65535
-A POSTROUTING -s 172.17.42.0/16 ! -d 172.17.42.0/16 -p udp -j MASQUERADE --to-ports 1016-65535
-A POSTROUTING -s 172.17.42.0/16 ! -d 172.17.42.0/16 -j MASQUERADE