iptables规则破坏了Docker容器之间的通信

3

nginx-proxy是一个Docker容器,作为其他容器的反向代理。它使用Docker API检测其他容器,并自动代理流量到它们。

我有一个简单的nginx-proxy设置:(其中subdomain.example.com被替换为我的域名)

docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
docker run -e VIRTUAL_HOST=subdomain.example.com kdelfour/cloud9-docker

当我的防火墙关闭时,它可以正常工作。当我打开防火墙时,nginx会返回504网关超时错误。这意味着我可以在80端口看到nginx,但我的防火墙规则似乎限制了容器之间和/或Docker API流量。
我创建了一个GitHub问题,但nginx代理的创建者说他从未遇到过这个问题。
以下是“关闭防火墙”的规则:(这些可以正常工作)
iptables -F
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

这是我的“开启防火墙”规则:(这些不起作用)
# Based on tutorial from http://www.thegeekstuff.com/scripts/iptables-rules / http://www.thegeekstuff.com/2011/06/iptables-rules-examples/

# Delete existing rules
iptables -F

# Set default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# Allow loopback access
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Allow inbound/outbound SSH
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

# Allow inbound/outbound HTTP
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

# Allow inbound/outbound HTTPS
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

# Ping from inside to outside
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
# Ping from outside to inside
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

# Allow outbound DNS
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

# Allow outbound NTP
iptables -A OUTPUT -p udp -o eth0 --dport 123 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 123 -j ACCEPT

# This bit is from https://blog.andyet.com/2014/09/11/docker-host-iptables-forwarding
# Docker Rules: Forward chain between docker0 and eth0.
iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o docker0 -j ACCEPT
ip6tables -A FORWARD -i docker0 -o eth0 -j ACCEPT
ip6tables -A FORWARD -i eth0 -o docker0 -j ACCEPT

iptables-save > /etc/network/iptables.rules

当我开启防火墙时,为什么代理无法工作?

1
你可以尝试在末尾添加 iptables -P FORWARD ACCEPT 吗?如果这样可以解决问题,那么问题就出在 FORWARD 链中。如果不行,你就需要查看 INPUT 或 OUTPUT 链了。 - Joel C
好的想法。我按照你的建议去做了,它起作用了(即问题在FORWARD链中)。我将开始研究这个问题,但如果有人找到解决方案,请务必提出来。 - Travis
我认为这是一个好的解决方案:iptables -A FORWARD -i docker0 -j ACCEPT - Travis
1个回答

4

感谢 Joel C 的建议(请参见上面的评论),我发现了FORWARD链上的问题,并进行了如下修复:

iptables -A FORWARD -i docker0 -j ACCEPT


注:本文内容涉及IT技术。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接