Fixing the firewall
1. The problem
If we create a test container, we will notice that the network in the container is not working:
incus launch images:ubuntu/22.04 u22
incus ls
incus exec u22 -- ip addr
The container did not get an IP, as it normally should.
However, if you stop firewalld and restart the container, everything works fine.
systemctl status firewalld
systemctl stop firewalld
incus restart u22
incus ls
incus exec u22 -- ip addr
incus exec u22 -- ping 8.8.8.8
systemctl start firewalld
systemctl status firewalld
So the problem is that the firewall is not configured properly. Let’s fix it.
2. Add the bridge interface to the trusted zone
Any interface that is not explicitly added to a zone, is added to the
default zone, which is the zone public. This zone is meant for the
interfaces that are facing the public internet, so it is
restricted. For example DHCP requests are blocked, and the containers
cannot get an IP.
To fix this, we can add the bridge interface to the trusted zone,
where everything is allowed:
firewall-cmd --zone=trusted --list-all
firewall-cmd --permanent --zone=trusted --add-interface=incusbr0
firewall-cmd --reload
firewall-cmd --zone=trusted --list-all
Let’s check that it is working:
incus restart u22
incus ls
incus exec u22 -- ip addr
incus exec u22 -- ping 8.8.8.8
3. Fix the FORWARD chain
If the ping is still not working, usually the problem is that
forwarding is blocked. If you try iptables-save | head and see
something like this: :FORWARD DROP [4:2508], it means that the
policy for the FORWARD chain is DROP. Maybe it is set by Docker,
if you have installed it.
You can make the default policy ACCEPT, like this: iptables -P
FORWARD ACCEPT. However, the next time that the server will be
rebooted, or firewalld restarted, you may loose this
configuration.
A better way is to add a direct (explicit) rule with
firewall-cmd, like this:
firewall-cmd --permanent --direct --add-rule \
ipv4 filter FORWARD 0 -j ACCEPT
firewall-cmd --reload
firewall-cmd --direct --get-all-rules
This will enable (ACCEPT) forwarding for all the interfaces, the current ones and the ones that will be created in the future. If this is not what you want, you can use more specific rules, like these:
firewall-cmd --permanent --direct --remove-rule \
ipv4 filter FORWARD 0 -j ACCEPT
firewall-cmd --permanent --direct --add-rule \
ipv4 filter -i incusbr0 FORWARD 0 -j ACCEPT
firewall-cmd --permanent --direct --add-rule \
ipv4 filter -o incusbr0 FORWARD 0 -j ACCEPT
firewall-cmd --reload
firewall-cmd --direct --get-all-rules