Docker与UFW防火墙共存
2023年9月22日 最终还是完全放弃了这个方案,这个方案在docker重启的时候会出现问题,把重启ufw和重启docker关联起来是很有问题的,确实在forward链上做防护更好。
“众所周知”,Docker和UFW(ubuntu自带的防火墙,Uncomplicated Firewall)等一系列防火墙都是不太能共存的。但是最近学校护网,需要打开防火墙。
UFW与Docker不能共存,肯定也有其他人忍不了。最知名的方案大概是ufw-docker项目。然而当我看到里面所说的为什么不选用在input链上做那一段的时候,我觉得我想要的就是在input链上防护!折腾由此开始。
最后用了这个回答的方案。
这个github issue 涉及的讨论,里面有人提到要改MANAGE_BUILTINS
操作步骤
- 修改
/etc/default/ufw
, 把no改成MANAGE_BUILTINS=yes - 修改
/etc/ufw/after.rules
(把下面的加到结尾) 注意把eno1改成网卡名字!!1
2
3
4
5
6
7
8
9# Put Docker behind UFW
*filter
:DOCKER-USER - [0:0]
:ufw-user-input - [0:0]
-A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # 只有加上这个才能允许docker的响应包回来。
-A DOCKER-USER -i eno1 -j ufw-user-input
-A DOCKER-USER -i eno1 -j DROP
COMMIT - 依次重启ufw和docker
1
2sudo ufw reload
sudo systemctl restart docker
背后的经验:
如果不增加MANAGE_BUILTINS=yes 刚开始的时候好像没事,但是后面(加规则?和)reload好像会导致ufw直接爆炸。似乎是ufw没有管理DOCKER-USER这个链,但是它引用了ufw-user-input,导致reload过程中关闭ufw的时候无法删掉ufw-user-input链,从而ufw爆炸,解决办法是用sudo iptables -X ufw-user-input手动删掉这个链
如果不重启docker,好像docker的网络直接紊乱了。启动需要转发端口的container的时候报错 1
2docker: Error response from daemon: driver failed programming external connectivity on endpoint laughing_northcutt (d38a235dfd7d9a54d19598945713b2d4c47a71eaaef4d9e4e1136d537656673e): (iptables failed: iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.2 --dport 80 -j ACCEPT: iptables: No chain/target/match by that name.
(exit status 1)).
最后一定要注意,每次重启ufw之后都要重启docker,因为MANAGE_BUILTINS=yes之后会把docker自己的ipatables规则都删掉!!需要重启docker增加一下它自己的规则。(经过对比前后iptables -L输出的区别发现)。