hi; I’m on Fedora 32 5.7.16-200.fc32.x86_64
,
with the package firewalld
: firewalld-0.8.3-1.fc32.noarch
,
and my Docker containers (all of them, with every image)
don’t have internet access by default, or any outside
connection aside from ping
, for that matter.
( for example, I can ping
by IP, but not by domain,
because I can’t reach the DNS server with a request )
I knew absolutely nothing about firewalls and firewalld
in particular before this, but I’ve been reading about it,
trying to understand the problem, and find the solution.
Besides the official firewalld
documentation, I’ve been
reading about incompatibilities between Docker
and firewalld
,
and a bunch of other things. I also know that,
exists podman
as a Docker
alternative.
But for me, this is not about: ‘make it work, and DONE’;
this is about understanding, as much as I can,
WHY
works when it does, and
WHY
does’t work when it doesn’t.
After learning about firewalld
, for me, seems correct that,
by default, the situation be like the one described above.
Now, I want to change that: I want to be able to ping
by domain, for example. When being blocked, logs from
the ping by domain says:
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
I tried different things; some of them, worked, and others don’t.
But some of them, I think should work, even when it doesn’t.
Seems like firewalld
is not honouring its rich rules
.
As far as I understood, you put a connection
in one zone
(and only one) by its interface
or source
, and then,
the zone
rules apply for the connection
:
if there are no rich rules
in the zone
,
the target
of the zone
(ACCEPT
,DROP
, etc)
applies for that connection
…
if there are rich rules
, and one matchs the connection
,
then that rich rule
is applied to that connection.
And, the first match ALWAYS wins.
What follows, is some output from my terminal, with
different tries, and each try is labeled, saying if it worked or not,
to give the docker container the hability to ping
by domain.
In my opinion, all for the tries bellow should do the trick…
some of them, are doing things that I don’t think are necessary,
like the tries that change the target
of the zone
to DROP
:
I did it, because I thought that maybe, the default target
was buggy.
So, my question is, why doesn’t work, when it doesn’t?
What is wrong?
defining variables for the container ip
and container interface
, to easily refer to them from now on:
CONTAINER_IP="172.18.0.2"
CONTAINER_INTERFACE="br-71fe7cc090b3"
defining a function to easily restore the firewalld
conf to default, and this way, I can completely restore the firewald conf before each try, knowing that all tries act on the same initial 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
}
WORKS on its own, from default restored firewalld
conf:
$ _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:
WORKS on its own, from default restored firewalld
conf:
$ _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:
WORKS on its own, from default restored firewalld
conf:
$ _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:
WORKS on its own, from default restored firewalld
conf:
$ _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:
WORKS on its own, from default restored firewalld
conf:
$ _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:
DOES NOT WORK on its own, from default restored firewalld
conf:
$ _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
DOES NOT WORK on its own, from default restored firewalld
conf:
$ _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
DOES NOT WORK on its own, from default restored firewalld
conf:
$ _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
DOES NOT WORK on its own, from default restored firewalld
conf:
$ _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
DOES NOT WORK on its own, from default restored firewalld
conf:
$ _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
DOES NOT WORK on its own, from default restored firewalld
conf:
$ _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