Using Docker with firewalld
TL;DR Trying to masquerade everything from Docker
with firewalld
manually.
I just started to use firewalld
on my Debian 10 machine since I want to learn how it works.
I have Docker
installed on the host and I want to manage the firewall by myself to learn more about what Docker does, what rules etc. it applies when containers are created and how firewalld works.
Since Debian 10 uses nftables
by default and use some kind of iptables
wrapper to be able to use iptables
commands to create firewall rules. Docker
runs just fine when --iptables
is enabled.
However I want to use firewalld
with nftables
backend and skip everything that has to do with iptables
since it's just confusing. So in /etc/systemd/system/multi-user.target.wants/docker.service
I added --iptables=false
so Docker doesn't mess with the firewall.
I flushed all the iptables rules etc. and all is good so far.
Now to my problem.
All containers can access the host and each other but not the internet. Since they all are running on 172.17.0.0/16 and my host is on 192.168.9.0/24 I need to masquerade the traffic from the containers.
I can't find much information about managing the firewall manually when using Docker and since I'm new to firewalld I'm kind of just guessing.
My interfaces are as follows:
eno1 (main interface)
docker0 (docker bridge)
veth******* (one for each container)
all the veth
interfaces are in the docker0
bridge.
So I thought I could create a new zone called docker
and masquerade everything from the docker0
bridge.
~# firewall-cmd --permanent --new-zone=docker
~# firewall-cmd --permanent --zone=docker --change-interface=docker0
~# firewall-cmd --permanent --zone=docker --add-rich-rule='rule family="ipv4" source address=172.17.0.0/16 masquerade'
~# firewall-cmd --reload
Listing the active zones gives me this:
~# firewall-cmd --get-active-zones
docker
interfaces: docker0
public
interfaces: eno1
I still can't access the internet from the containers. I have no idea if this is the right way to go or what I'm missing. Any help is appreciated.
Solution 1:
In firewalld, masquerading needs to be set on the zone which leads out to the Internet. In your case, that seems to be the public
zone.