TLDR; --向docker容器添加了一些iptable规则以限制Internet访问。工作正常,除了现在我无法从主机访问容器应用程序,但可以从容器本身内部访问容器
我有一个运行Web应用程序的容器。该容器使用mysql
,redis
等。每个依赖项都是远程的,可以通过IP地址在特定端口上访问。
例如,可以在ip 13.255.255.255上访问mysql
我想要的是只允许容器使用mysql ip地址,而不能使用其他IP。很少有curl
请求来自代码内的请求,我不想超出我的主机网络。
我在docker中添加了一个入口点脚本,该脚本在容器中添加了一些iptables
规则。
ALLOWED_CIDR1=172.0.0.0/16
ALLOWED_CIDR2=13.255.255.255 #For mysql access
#iptables -P FORWARD DROP # we aren't a router
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -s 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
iptables -P INPUT DROP # Drop everything we don't accept
iptables -A INPUT -s 0.0.0.0 -j ACCEPT
iptables -A INPUT -s ::1 -j ACCEPT
iptables -A OUTPUT -d ::1 -j ACCEPT
iptables -A INPUT -s $ALLOWED_CIDR1 -j ACCEPT
iptables -A INPUT -s $ALLOWED_CIDR1 -j ACCEPT
iptables -A OUTPUT -d $ALLOWED_CIDR2 -j ACCEPT
iptables -A OUTPUT -d $ALLOWED_CIDR2 -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
当我运行容器并执行
docker-compose exec <container-name> curl http://google.com
我得到以下回应:
卷曲:(6)无法解析主机:google.com
这是预期的。现在,当我这样做
docker-compose exec <container-name> curl http://0.0.0.0
我得到以下回应:
“世界你好!”
再次期望。但是,当我从主机上执行curl http://0.0.0.0
时,输出如下
* Trying 0.0.0.0...
* TCP_NODELAY set
* Connected to 0.0.0.0 (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: 0.0.0.0
> User-Agent: curl/7.62.0
> Accept: */*
> // Hangs here
因此,我无法从主机连接到http://0.0.0.0,但可以从docker内部连接。
答案 0 :(得分:0)
我完全愚蠢地忽略了自己发布的iptables规则。
错误的规则集
ALLOWED_CIDR1=172.0.0.0/16
ALLOWED_CIDR2=13.255.255.255 #For mysql access
#iptables -P FORWARD DROP # we aren't a router
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -s 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
iptables -P INPUT DROP # Drop everything we don't accept
iptables -A INPUT -s 0.0.0.0 -j ACCEPT
iptables -A INPUT -s ::1 -j ACCEPT
iptables -A OUTPUT -d ::1 -j ACCEPT
iptables -A INPUT -s $ALLOWED_CIDR1 -j ACCEPT
iptables -A INPUT -s $ALLOWED_CIDR1 -j ACCEPT
iptables -A OUTPUT -d $ALLOWED_CIDR2 -j ACCEPT
iptables -A OUTPUT -d $ALLOWED_CIDR2 -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
您可以在上一节中看到
192.168.x.x
没有 OUTPUT ACCEPT 规则,该规则是我的docker-0
网络接口的ip地址如果在启动容器时使用了网络模式docker0
,则docker和主机都使用bridged
网络接口进行通信(碰巧是我的情况)。
我注意到的另一件事是,我根本不需要0.0.0.0
或127.0.0.1
规则。由于入口点脚本将在docker容器中添加iptable规则,因此我们可能永远都不想从容器本身访问webapp。因此,为什么还要打扰127.0.0.1?
总而言之,这就是我所做的:
docker0
网络的IP地址。 ip addr show docker0
。它输出了192.168.144.1/20 我的iptable规则现在看起来像这样:
ALLOWED_CIDR1=172.0.0.0/16
ALLOWED_CIDR2=13.255.255.255
ALLOWED_CIDR3=192.168.0.0/16
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -P INPUT DROP # Drop everything we don't accept
iptables -P OUTPUT DROP
iptables -A INPUT -s $ALLOWED_CIDR1 -j ACCEPT
iptables -A INPUT -s $ALLOWED_CIDR2 -j ACCEPT
iptables -A INPUT -s $ALLOWED_CIDR3 -j ACCEPT
iptables -A OUTPUT -d $ALLOWED_CIDR1 -j ACCEPT
iptables -A OUTPUT -d $ALLOWED_CIDR2 -j ACCEPT
iptables -A OUTPUT -d $ALLOWED_CIDR3 -j ACCEPT