问题描述
这是我第一次设置 Ubuntu Server (14.04 LTS),但在配置防火墙 (UFW) 时遇到问题。
我只需要 ssh
和 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
但是我仍然可以连接到这台机器其他端口上的数据库。知道我做错了什么吗?
编辑:这些数据库位于 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
未显示这些更改。
可能的解决方案是:
-
停止使用
-p
标志。请改用 docker 链接或 docker networks。 -
在本地绑定容器,这样它们就不会暴露在您的机器之外:
docker run -p 127.0.0.1:8080:8080 ...
-
如果您坚持使用
-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 中的适当规则。
第三种办法
如果您使用的是 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.conf
和 iptables-restore < /tmp/iptables.conf
转储、编辑和恢复 iptables 规则。
第五种办法
一个快速的解决方法是在运行 Docker 并进行端口映射时。你总能做到
docker run ...-p 127.0.0.1:<ext pot>:<internal port> ...
以防止您的 Docker 被外部访问。