手动为 Docker 配置 iptables 并允许容器访问 Internet

手动为 Docker 配置 iptables 并允许容器访问 Internet

我对 Docker 修改防火墙规则的行为非常不满,因为它会打开我服务器上的所有端口。
因此,我安装并设置了一些防火墙规则,阻止除端口 22、80 和 443 之外的所有传入流量,并通过创建以下内容iptables-persistent确保 Docker 不会干扰这些规则:/etc/systemd/system/docker.service.d/noiptables.conf

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --iptables=false -H "fd://"

然后重新启动服务器。

现在我的问题是我的 Docker 容器无法再访问互联网(接口:ens3)。

这些是我的规则:

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ens3 -j MASQUERADE
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Allow localhost
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

# ICMP
-A INPUT -p icmp -j ACCEPT

# Docker
-A FORWARD -i docker0 -o ens3 -j ACCEPT
-A FORWARD -i ens3 -o docker0 -j ACCEPT


# Incoming
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -j DROP

# Outgoing
-A OUTPUT -j ACCEPT

# Routing
-A FORWARD -j DROP


COMMIT

我将它们存储在/etc/iptables/rules.v4和中,/etc/iptables/rules.v6并通过运行确保它们被加载sudo netfilter-persistent reload

根据本指南:https://blog.daknob.net/debian-firewall-docker/*nat部分本来可以完成这项工作,但是它却没有。

我的系统:

$ sudo iptables --version
iptables v1.6.1

$ uname -r
4.11.0-1-amd64

$ sudo lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux testing (buster)
Release:        testing
Codename:       buster

答案1

首先,您从未提及过net.ipv4.ip_forward net.ipv4.ip_forward。如果还没有,请启用它。

确保您可以访问互联网。curl httpbin.org/ip这是一种简单且方便的检查方法。

如果这样做,请通过检查输出来确保您的规则有效iptables-save

如果是,则进行调试,以下是伪步骤:

  1. 在 docker 内部,ping 一个外部 IP,8.8.8.8并确保您没有收到任何回复。不要使用主机名。让我们将 DNS 问题排除在我们的场景之外。保持它运行以进行下一步。

  2. 在容器内部,使用 tcpdump 逐个检查所有接口,并查找发往 8.8.8.8 的包。根据您粘贴到问题中的规则,这必须是 docker0。

  3. 检查主机的路由表并确保默认路由 0.0.0.0 在接口 ens3 上

您应该获得足够的信息来解决问题。

相关内容