当前位置: 首页>>技术教程>>正文


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

, , , ,

问题描述

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

我只需要 sshhttp ,所以我这样做:

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

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

编辑:这些数据库位于 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)

最佳办法

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

事实证明,Docker 直接在您的 iptables 上进行更改,而 ufw status 未显示这些更改。

可能的解决方案是:

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

  2. 在本地绑定容器,这样它们就不会暴露在您的机器之外:docker run -p 127.0.0.1:8080:8080 ...

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

我推荐选项 1 或 2。请注意选项 3 has side-effects ,例如容器无法连接到互联网。

次佳办法

16.04 提出了新的挑战。我完成了 Running Docker behind the ufw firewall 所示的所有步骤,但我无法让 docker plus UFW 在 16.04 上工作。换句话说,无论我做什么,所有的 docker 端口都会在全球范围内暴露在互联网上。直到我发现这个:How to set Docker 1.12+ to NOT interfere with IPTABLES/FirewallD

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

{
    "iptables": false
}

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

附加数据:Docker overrules UFW!

第三种办法

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

{   "iptables" : false }

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

如果您启用了 UFW,请确认您可以从容器内部访问 Internet。如果不是 – 您必须在 /etc/default/ufw 上将 DEFAULT_FORWARD_POLICY 定义为 ACCEPT 并应用此处描述的技巧:https://stackoverflow.com/a/17498195/507564

第四种办法

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

根据 ESala’s answer

If you use -p flag on containers Docker makes changes directly to iptables, ignoring the 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

将包从 ‘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

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

-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

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

第五种办法

一个快速的解决方法是在运行 Docker 并进行端口映射时。你总能做到

docker run ...-p 127.0.0.1:<ext pot>:<internal port> ...

以防止您的 Docker 被外部访问。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/12413.html,未经允许,请勿转载。