使用 Docker 时,简单防火墙 (UFW) 不会阻止任何事情

ESa*_*ala 67 firewall networking ufw 14.04 docker

这是我第一次设置 Ubuntu 服务器 (14.04 LTS),我在配置防火墙 (UFW) 时遇到问题。

我只需要sshand http,所以我这样做:

sudo ufw disable

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp

sudo ufw enable
sudo reboot
Run Code Online (Sandbox Code Playgroud)

但是我仍然可以连接到这台机器其他端口上的数据库。知道我做错了什么吗?

编辑:这些数据库位于 Docker 容器上。这可能有关系吗?它是否覆盖了我的 ufw 配置?

EDIT2:输出sudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
Run Code Online (Sandbox Code Playgroud)

ESa*_*ala 105

问题是-p在容器上使用标志。

原来,泊坞窗的变化直接对你iptables,这是不显示ufw status

可能的解决方案是:

  1. 停止使用该-p标志。请改用 docker 链接或docker 网络

  2. 在本地绑定容器,使其不会暴露在您的机器之外:

    docker run -p 127.0.0.1:8080:8080 ...

  3. 如果您坚持使用该-p标志,请iptables通过禁用它们/etc/docker/daemon.json并重新启动来告诉 docker 不要触摸您的标志:

    { "iptables" : false }

我推荐选项 1 或 2。请注意选项 3有副作用,例如容器无法连接到 Internet。

  • 这非常有用 - 我为能够访问我在 ufw 中不允许的端口而发疯。但是,使用 iptables=false 会中断很多,例如容器可以在本地主机上访问,例如用于反向代理。最好确保容器侦听正确,不要使用 -p 80:80 而是使用 -p 127.0.0.1:80:80 或不同的端口,如 127.0.0.1:3000:80 用于使用 nginx 或 apache 进行反向代理并且没有端口冲突。 (12认同)
  • @AndreasReiff 你是对的,但最近我发现最好尽可能避免使用 `-p`。例如,在反向代理的情况下,我不会为工作容器映射任何端口,然后将 nginx 放入它自己的容器中,使用 `-p 80:80` 和一个 `--link` 到其他容器。这样就不会有任何端口冲突,唯一的访问点是通过 nginx。 (2认同)
  • 另请查看这篇文章,了解您必须采取的第三项预防措施!https://svenv.nl/unixandlinux/dockerufw (2认同)
  • *重要*:`/etc/default/docker` 是 upstart config 使用的配置文件。如果您已从 upstart 迁移到 systemd,则不会使用此文件。 (2认同)

小智 8

16.04 带来了新的挑战。我完成了所有步骤,如在 ufw 防火墙后面运行 Docker 所示,我无法让 docker plus UFW 在 16.04 上工作。换句话说,无论我做什么,所有 docker 端口都在全球范围内暴露在互联网上。直到我发现这个:如何设置 Docker 1.12+ 以不干扰 IPTABLES/FirewallD

我必须创建文件/etc/docker/daemon.json并将以下内容放入:

{
    "iptables": false
}
Run Code Online (Sandbox Code Playgroud)

然后我发出sudo service docker stop最后sudo service docker startdocker 只是遵循 UFW 中的适当规则。

附加数据:Docker 否决了 UFW!

  • 对于 Ubuntu 16.04 和 Docker 版本 17.09,此解决方案会中断来自容器的出站连接。请参阅回复 https://askubuntu.com/a/833363/262702 和 https://askubuntu.com/a/954041/262702 (2认同)

ors*_*har 6

如果您使用的是 systemd(Ubuntu 15.10 及更高版本)的 init 系统,请编辑/etc/docker/daemon.json(如果它不存在,则可能需要创建它),确保它已iptables配置密钥:

{   "iptables" : false }
Run Code Online (Sandbox Code Playgroud)

编辑:这可能会导致您从容器内部失去与互联网的连接

如果您启用了 UFW,请验证您是否可以从容器内部访问 Internet。如果不是 - 您必须定义DEFAULT_FORWARD_POLICYACCEPTon/etc/default/ufw并应用此处描述的技巧:https : //stackoverflow.com/a/17498195/507564


小智 5

就我而言,我最终修改了 iptables 以允许仅从特定 IP 访问 Docker。

根据ESala 的回答

如果您-p在容器上使用标志,Docker 会直接更改 iptables,忽略 ufw。

Docker 添加到 iptables 的记录示例

路由到“DOCKER”链:

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
Run Code Online (Sandbox Code Playgroud)

将数据包从“DOCKER”链转发到容器:

-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination 172.17.0.3:6379
Run Code Online (Sandbox Code Playgroud)

您可以修改 iptables 以允许仅从指定的源 IP 访问 DOCKER 链(例如1.1.1.1):

-A PREROUTING -s 1.1.1.1 -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -s 1.1.1.1 ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
Run Code Online (Sandbox Code Playgroud)

您可能想要使用iptables-save > /tmp/iptables.confiptables-restore < /tmp/iptables.conf来转储、编辑和恢复 iptables 规则。