我有一台CentOS 7的电脑,原本使用它iptables
作为防火墙配置工具。
计算机有一个监听端口的docker容器10079
。
我想用firewalld
来代替iptables
。
firewalld
和都iptables
在 docker 容器外运行。我不在容器内运行它们。
所以我运行以下命令
$ systemctl stop iptables
# disable iptables so that it doesn't start at next system reboot.
$ systemctl disable iptables
$ systemctl start firewalld
$ systemctl enable firewalld
$ firewall-cmd --list-services
dhcpv6-client ssh
从输出命令可以看出firewall-cmd --list-services
,我只启用了ssh
、 和dhcpv6-client
服务。
不过有一点比较奇怪,就是我仍然可以通过端口访问服务器10079
。
我以为运行命令后,链的规则iptables
就会失效。systemctl stop iptables
但我错了。因为我仍然可以通过端口 10079 访问计算机上的服务。
10079
为什么运行命令后仍然可以访问端口systemctl stop iptables
?
以下iptables
是firewalld
$ systemctl status iptables
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
Active: inactive (dead) since Fri 2021-06-18 16:56:38 CST; 47min ago
Process: 18324 ExecStop=/usr/libexec/iptables/iptables.init stop (code=exited, status=0/SUCCESS)
Process: 18220 ExecStart=/usr/libexec/iptables/iptables.init start (code=exited, status=0/SUCCESS)
Main PID: 18220 (code=exited, status=0/SUCCESS)
Jun 18 16:56:22 foo.my-company.com systemd[1]: Starting IPv4 firewall with iptables...
Jun 18 16:56:22 foo.my-company.com iptables.init[18220]: iptables: Applying firewall rules: [ OK ]
Jun 18 16:56:22 foo.my-company.com systemd[1]: Started IPv4 firewall with iptables.
Jun 18 16:56:38 foo.my-company.com systemd[1]: Stopping IPv4 firewall with iptables...
Jun 18 16:56:38 foo.my-company.com iptables.init[18324]: iptables: Setting chains to policy ACCEPT: nat mangle security raw fil...OK ]
Jun 18 16:56:38 foo.my-company.com iptables.init[18324]: iptables: Flushing firewall rules: [ OK ]
Jun 18 16:56:38 foo.my-company.com systemd[1]: Stopped IPv4 firewall with iptables.
Hint: Some lines were ellipsized, use -l to show in full.
$ systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-06-18 16:56:38 CST; 48min ago
Docs: man:firewalld(1)
Main PID: 18325 (firewalld)
Tasks: 2
Memory: 26.0M
CGroup: /system.slice/firewalld.service
└─18325 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
Jun 18 16:56:38 foo.my-company.com systemd[1]: Starting firewalld - dynamic firewall daemon...
Jun 18 16:56:38 foo.my-company.com systemd[1]: Started firewalld - dynamic firewall daemon.
Jun 18 16:56:39 foo.my-company.com firewalld[18325]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure con...t now.
Jun 18 16:56:39 foo.my-company.com firewalld[18325]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-e06022...ain?).
Jun 18 16:56:39 foo.my-company.com firewalld[18325]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-ee12e0...ain?).
Jun 18 16:56:39 foo.my-company.com firewalld[18325]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-37072d...ain?).
Jun 18 16:56:39 foo.my-company.com firewalld[18325]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i docker0 -...ain?).
Jun 18 16:56:39 foo.my-company.com firewalld[18325]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-95db75...ain?).
Jun 18 16:56:39 foo.my-company.com firewalld[18325]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-d77a44...ain?).
Jun 18 16:56:40 foo.my-company.com firewalld[18325]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i docker0 -...ain?).
Hint: Some lines were ellipsized, use -l to show in full.
看起来它firewalld
已正确启动,并且iptables
已被禁用。
/var/log/firewalld
以下是我现在重新启动计算机时的内容:
2021-06-18 22:13:19 WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t nat -D PREROUTING -m addrtype --dst-type LOCAL -j DOCKER' failed: iptables v1.4.21: Couldn't load target `DOCKER':No such file or directory
Try `iptables -h' or 'iptables --help' for more information.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t nat -D OUTPUT -m addrtype --dst-type LOCAL ! --dst 127.0.0.0/8 -j DOCKER' failed: iptables v1.4.21: Couldn't load target `DOCKER':No such file or directory
Try `iptables -h' or 'iptables --help' for more information.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t nat -D OUTPUT -m addrtype --dst-type LOCAL -j DOCKER' failed: iptables v1.4.21: Couldn't load target `DOCKER':No such file or directory
Try `iptables -h' or 'iptables --help' for more information.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t nat -D PREROUTING' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t nat -D OUTPUT' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t nat -F DOCKER' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t nat -X DOCKER' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -F DOCKER' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -X DOCKER' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -F DOCKER-ISOLATION-STAGE-1' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -X DOCKER-ISOLATION-STAGE-1' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -F DOCKER-ISOLATION-STAGE-2' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -X DOCKER-ISOLATION-STAGE-2' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -F DOCKER-ISOLATION' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -X DOCKER-ISOLATION' failed: iptables: No chain/target/match by that name.
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-ee12e0b3bd4b -o br-ee12e0b3bd4b -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:21 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-37072db2b0a2 -o br-37072db2b0a2 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:22 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-95db758dd575 -o br-95db758dd575 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:22 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i docker0 -o docker0 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:22 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-d77a4470f1ee -o br-d77a4470f1ee -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:22 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i br-e06022f15557 -o br-e06022f15557 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
2021-06-18 22:13:22 WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i docker0 -o docker0 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).
日志内容包含了很多关于docker的警告,可能这个问题和docker有关系。
这是我当前的 iptables 设置。
$ iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
INPUT_direct all -- 0.0.0.0/0 0.0.0.0/0
INPUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0
INPUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-1 all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
FORWARD_direct all -- 0.0.0.0/0 0.0.0.0/0
FORWARD_IN_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0
FORWARD_IN_ZONES all -- 0.0.0.0/0 0.0.0.0/0
FORWARD_OUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0
FORWARD_OUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
OUTPUT_direct all -- 0.0.0.0/0 0.0.0.0/0
Chain DOCKER (6 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 172.21.0.2 tcp dpt:443
ACCEPT tcp -- 0.0.0.0/0 192.168.208.2 tcp dpt:8005
ACCEPT tcp -- 0.0.0.0/0 172.29.0.3 tcp dpt:8080
ACCEPT tcp -- 0.0.0.0/0 172.20.0.3 tcp dpt:5432
ACCEPT tcp -- 0.0.0.0/0 172.21.0.3 tcp dpt:5432
ACCEPT tcp -- 0.0.0.0/0 172.20.0.4 tcp dpt:80
ACCEPT tcp -- 0.0.0.0/0 172.21.0.4 tcp dpt:9000
ACCEPT tcp -- 0.0.0.0/0 172.20.0.4 tcp dpt:22
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-2 (6 references)
target prot opt source destination
DROP all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD_IN_ZONES (1 references)
target prot opt source destination
FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
Chain FORWARD_IN_ZONES_SOURCE (1 references)
target prot opt source destination
Chain FORWARD_OUT_ZONES (1 references)
target prot opt source destination
FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
Chain FORWARD_OUT_ZONES_SOURCE (1 references)
target prot opt source destination
Chain FORWARD_direct (1 references)
target prot opt source destination
Chain FWDI_public (2 references)
target prot opt source destination
FWDI_public_log all -- 0.0.0.0/0 0.0.0.0/0
FWDI_public_deny all -- 0.0.0.0/0 0.0.0.0/0
FWDI_public_allow all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
Chain FWDI_public_allow (1 references)
target prot opt source destination
Chain FWDI_public_deny (1 references)
target prot opt source destination
Chain FWDI_public_log (1 references)
target prot opt source destination
Chain FWDO_public (2 references)
target prot opt source destination
FWDO_public_log all -- 0.0.0.0/0 0.0.0.0/0
FWDO_public_deny all -- 0.0.0.0/0 0.0.0.0/0
FWDO_public_allow all -- 0.0.0.0/0 0.0.0.0/0
Chain FWDO_public_allow (1 references)
target prot opt source destination
Chain FWDO_public_deny (1 references)
target prot opt source destination
Chain FWDO_public_log (1 references)
target prot opt source destination
Chain INPUT_ZONES (1 references)
target prot opt source destination
IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
Chain INPUT_ZONES_SOURCE (1 references)
target prot opt source destination
Chain INPUT_direct (1 references)
target prot opt source destination
Chain IN_public (2 references)
target prot opt source destination
IN_public_log all -- 0.0.0.0/0 0.0.0.0/0
IN_public_deny all -- 0.0.0.0/0 0.0.0.0/0
IN_public_allow all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
Chain IN_public_allow (1 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED
Chain IN_public_deny (1 references)
target prot opt source destination
Chain IN_public_log (1 references)
target prot opt source destination
Chain OUTPUT_direct (1 references)
target prot opt source destination
答案1
Firewalld 在内核中的 iptables 之上添加了一个抽象层。虽然该systemctl stop iptables
命令可能停止了用于管理链的用户空间实用程序,但内核配置似乎并未因此而改变(如果我猜的话,停止该服务可能会保存链,从而使您在重新启动之间保留设置)。
Docker 本身对内核的 iptables 设置进行了大量管理,以配置容器之间和主机之间的网络。除了创建桥接网络和虚拟以太网设备之外,还创建了 NAT 规则,以允许容器作为主机连接到网络。对于端口转发(从主机到容器),有一个docker-proxy
侦听的用户空间进程和各种转发规则的组合。当您发布端口时,所有这些都会自动配置,并绕过您在像 Firewalld 这样的工具中配置的任何过滤规则。您可以在表中看到这一点,FORWARD
其中各种DOCKER
表条目是在各种*_ZONES
条目之前创建的。
如果要在已发布的端口上设置防火墙策略,则过程是使用该DOCKER-USER
表,并结合 conntrack 来处理 NAT 所做的混淆。结果如下所示:
# Drop external requests by default.
# This rule is first because these are each insert at the top of the chain
# so the first insert becomes the last rule run in the chain.
# By default the DOCKER-USER table contains a single RETURN entry for
# everything so other rules must be insert before this.
iptables -I DOCKER-USER -j DROP
# allow existing requests
iptables -I DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
# allow inter-container requests
iptables -I DOCKER-USER -i br+ -j RETURN
# allow request from docker to external
iptables -I DOCKER-USER -i docker+ -j RETURN
# allow anything to host port 5000
iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdstport 5000 -j RETURN