我使用的是 Fedora 32 5.7.16-200.fc32.x86_64
,带有包firewalld
: firewalld-0.8.3-1.fc32.noarch
,并且我的 Docker 容器(所有容器,每个镜像)默认情况下没有互联网访问权限,也没有除 之外的任何外部连接ping
。 (例如,我可以ping
通过IP,但不能通过域,因为我无法通过请求到达DNS服务器)
我对防火墙一无所知,firewalld
尤其是在此之前,但我一直在阅读有关防火墙的内容,试图理解问题并找到解决方案。
除了官方firewalld
文档之外,我还阅读了有关Docker
和之间的不兼容性firewalld
以及许多其他内容的信息。我也知道,存在podman
作为Docker
替代方案。
但对我来说,这并不是“让它发挥作用,完成”;而是“让它发挥作用,完成”。这是关于尽我所能地理解,
WHY
当它有效时有效,当
WHY
无效时无效。
在了解之后firewalld
,对我来说,似乎正确的是,默认情况下,情况就像上面描述的那样。
现在,我想改变这一点:例如,我希望能够通过域进行 ping 操作。被阻止时,来自域的 ping 日志显示:
FINAL_REJECT: IN="$CONTAINER_INTERFACE" OUT=wlp3s0 PHYSIN=vethb53e882 MAC=XX:....:XX SRC="$CONTAINER_IP" DST=1.1.1.1 LEN=56 TOS=0x00 PREC=0x00 TTL=63 ID=37255 DF PROTO=UDP SPT=57463 DPT=53 LEN=36
我尝试了不同的事情;其中一些有效,而另一些则无效。但我认为其中一些应该有效,即使它不起作用。
看来firewalld
是不兑现了rich rules
。据我了解,您将 a通过其或放入connection
一个zone
(且只有一个)中,然后,规则适用于:如果中没有,则( 、等) 的适用于该...如果存在,并且其中一个与 相匹配,则该值将应用于该连接。而且,第一场比赛总是获胜。interface
source
zone
connection
rich rules
zone
target
zone
ACCEPT
DROP
connection
rich rules
connection
rich rule
接下来是我的终端的一些输出,具有不同的尝试,并且每次尝试都被标记,说明它是否有效,以便为 docker 容器提供ping
按域进行操作的能力。
在我看来,下面的所有尝试都应该可以解决问题......其中一些尝试正在做我认为不必要的事情,例如将target
的更改为 的尝试:我做到了,因为我认为也许,那是越野车。所以,我的问题是,当它不起作用时,为什么不起作用?怎么了?zone
DROP
default target
container ip
为和定义变量container interface
,以便从现在起轻松引用它们:
CONTAINER_IP="172.18.0.2"
CONTAINER_INTERFACE="br-71fe7cc090b3"
定义一个函数来轻松地将firewalld
conf恢复为默认值,这样,我可以在每次尝试之前完全恢复firewald conf,知道所有尝试都作用于相同的初始conf:
_restore_firewalld() {
sudo cp -Ta /usr/lib/firewalld/ /etc/firewalld/ && \
sudo restorecon -r /etc/firewalld/ && \
sudo firewall-cmd --complete-reload && \
sudo firewall-cmd --set-log-denied=unicast ##to log rejects
}
可以独立工作,从默认恢复的firewalld
配置:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=docker --add-source="$CONTAINER_IP" && \
$ sudo firewall-cmd --reload && \
success
Warning: ALREADY_SET: unicast
success
success
success
$ sudo firewall-cmd --info-zone=docker
docker (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: docker0
sources: 172.18.0.2
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
可以独立工作,从默认恢复的firewalld
配置:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=trusted --add-source="$CONTAINER_IP" && \
$ sudo firewall-cmd --reload && \
success
Warning: ALREADY_SET: unicast
success
success
success
$ sudo firewall-cmd --info-zone=trusted
trusted (active)
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources: 172.18.0.2
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
可以独立工作,从默认恢复的firewalld
配置:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=docker --add-interface="$CONTAINER_INTERFACE" && \
$ sudo firewall-cmd --reload && \
success
Warning: ALREADY_SET: unicast
success
success
success
$ sudo firewall-cmd --info-zone=docker
docker (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: br-71fe7cc090b3 docker0
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
可以独立工作,从默认恢复的firewalld
配置:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=trusted --add-interface="$CONTAINER_INTERFACE" && \
$ sudo firewall-cmd --reload && \
success
Warning: ALREADY_SET: unicast
success
success
success
$ sudo firewall-cmd --info-zone=trusted
trusted (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: br-71fe7cc090b3
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
可以独立工作,从默认恢复的firewalld
配置:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=public --set-target=ACCEPT && \
$ sudo firewall-cmd --permanent --zone=public --add-source="$CONTAINER_IP" && \
$ sudo firewall-cmd --reload && \
success
Warning: ALREADY_SET: unicast
success
success
success
$ sudo firewall-cmd --info-zone=public
success
public (active)
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources: 172.18.0.2
services: dhcpv6-client mdns ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
从默认恢复的配置中,它本身不起作用firewalld
:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=docker --add-rich-rule="rule family=ipv4 source address="$CONTAINER_IP" accept" && \
$ sudo firewall-cmd --reload
success
Warning: ALREADY_SET: unicast
success
success
success
$ sudo firewall-cmd --info-zone=docker
docker (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: docker0
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="172.18.0.2" accept
从默认恢复的配置中,它本身不起作用firewalld
:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address="$CONTAINER_IP" accept" && \
$ sudo firewall-cmd --reload
success
Warning: ALREADY_SET: unicast
success
success
success
$ sudo firewall-cmd --info-zone=public
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client mdns ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="172.18.0.2" accept
从默认恢复的配置中,它本身不起作用firewalld
:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=public --add-source="$CONTAINER_IP" && \
$ sudo firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address="$CONTAINER_IP" accept" && \
$ sudo firewall-cmd --reload
success
Warning: ALREADY_SET: unicast
success
success
success
success
$ sudo firewall-cmd --info-zone=public
public (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 172.18.0.2
services: dhcpv6-client mdns ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="172.18.0.2" accept
从默认恢复的配置中,它本身不起作用firewalld
:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=public --set-target=DROP && \
$ sudo firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address="$CONTAINER_IP" accept" && \
$ sudo firewall-cmd --reload
success
Warning: ALREADY_SET: unicast
success
success
success
success
$ sudo firewall-cmd --info-zone=public
public
target: DROP
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client mdns ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="172.18.0.2" accept
从默认恢复的配置中,它本身不起作用firewalld
:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=public --set-target=DROP && \
$ sudo firewall-cmd --permanent --zone=public --add-source="$CONTAINER_IP" && \
$ sudo firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address="$CONTAINER_IP" accept" && \
$ sudo firewall-cmd --reload
success
Warning: ALREADY_SET: unicast
success
success
success
success
success
$ sudo firewall-cmd --info-zone=public
public (active)
target: DROP
icmp-block-inversion: no
interfaces:
sources: 172.18.0.2
services: dhcpv6-client mdns ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="172.18.0.2" accept
从默认恢复的配置中,它本身不起作用firewalld
:
$ _restore_firewalld && /
$ sudo firewall-cmd --permanent --zone=public --add-interface="$CONTAINER_INTERFACE" && \
$ sudo firewall-cmd --permanent --zone=public --add-source="$CONTAINER_IP" && \
$ sudo firewall-cmd --permanent --zone=public --add-rich-rule="rule family=ipv4 source address="$CONTAINER_IP" accept" && \
$ sudo firewall-cmd --reload
success
Warning: ALREADY_SET: unicast
success
success
success
success
success
$ sudo firewall-cmd --info-zone=public
public (active)
target: default
icmp-block-inversion: no
interfaces: br-71fe7cc090b3
sources: 172.18.0.2
services: dhcpv6-client mdns ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="172.18.0.2" accept