限制可以从 docker 容器内访问的 IP 地址的最佳方法是什么?

What is the best way to limit the IP addresses which can be access from within a docker container?

我有一个答案,它将限制 docker 个容器只能访问主机外部的单个 IP 地址。在主机上使用此 iptables 规则:

# iptables -I FORWARD -i docker0  ! -d 8.8.8.8 -j DROP

意味着从任何 docker 容器内部只能访问 IP 地址 8.8.8.8。

这相当激烈 - 基本上,如果目标不是 8.8.8.8,则丢弃数据包。

设置允许我将容器限制为特定数量 IP 地址的规则的最佳方法是什么?

呸!!!

漫长的一天 - 没有借口等等...

我假设我可以按照...添加一些记录...

如果 IP1 则允许。 如果 IP2 则允许。 如果 IP3 则允许。 其他一切然后下降。

这似乎有效:

# iptables -I FORWARD -i docker0  -j DROP
# iptables -I FORWARD -i docker0  -d 8.8.8.8 -j ACCEPT
# iptables -I FORWARD -i docker0  -d 4.2.2.2 -j ACCEPT

这导致 iptables 规则:

root@jessie-amd64:~# iptables -L -n 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            4.2.2.2             
ACCEPT     all  --  0.0.0.0/0            8.8.8.8             
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:3306
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:22
root@jessie-amd64:~#

iptables 的最佳做法是首先删除所有 IP 或端口中的所有内容。然后单独打开一些端口。

这是我用来管理端口的示例(脚本),但我假设您可以对 IP 执行相同的操作:

#!/bin/sh

# reset :
iptables -t filter -F
iptables -t filter -X

# Block all :
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT DROP

# Authorize already established connections :
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Authorize backloop :
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT

# Authorize ssh :
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT

# Authorize HTTP :
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT

# Authorize HTTPS :
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 443 -j ACCEPT

# Authorize DNS :
iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT

# Ping :
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT

# Authorize FTP :
iptables -t filter -A INPUT -p tcp --dport 20 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 20 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 21 -j ACCEPT

# # Authorize NTP :
# iptables -t filter -A INPUT -p udp --dport 123 -j ACCEPT
# iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT

# Authorize IRC :
iptables -t filter -A INPUT -p tcp --dport 6667 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 6667 -j ACCEPT

# Authorize port 10000 (for Node.JS server) :
iptables -t filter -A INPUT -p tcp --dport 10000 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 10000 -j ACCEPT

# Authorize port 631 (Cups server) :
iptables -t filter -A INPUT -p tcp --dport 631 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 631 -j ACCEPT

希望对您有所帮助。

如果你有一个你想要允许访问的特定地址的列表,你可能想要研究 ipset 命令,它允许你在内核中维护一个 ip 地址列表,可以由 iptables 规则使用。这可能会大大简化您的规则集。

创建一个新的 ipset:

ipset create dockerdests hash:ip

向集合中添加一些地址:

ipset add dockerdests 8.8.8.8
ipset add dockerdests 162.13.208.130

创建引用该集的 iptables 规则:

iptables -I FORWARD 1 -i docker0 -m set --match-set dockerdests dst -j ACCEPT
iptables -I FORWARD 2 -i docker0 -j DROP

这些命令在 FORWARD 链的顶部插入两条规则;第一条将接受从 来自 的任何在命名 ip 集中列出的数据包,第二条规则将丢弃任何来自 [=15] 的数据包=] 之前的规则不接受。

如果你走这条路,你需要安排在系统启动时加载你的 ipset 配置。

可以找到有关 ipset 的更多信息 here