我在 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
。据我所知,您将 放在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
为默认值,这样,我可以在每次尝试之前完全恢复防火墙配置,并且知道所有尝试都针对相同的初始配置进行操作:
_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