限制可以从 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。
我有一个答案,它将限制 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。