Managing Docker Container Firewall Rules with firewalld
Previously, I used ufw
to restrict all incoming traffic except for port 80
, specifically allowing only Cloudflare IPs. However, it was too complicated to manage the firewall rules using ufw
. I decided to explore other options, including using firewalld
for managing Docker container firewall rules.
Introduction to firewalld
firewalld
is a dynamic firewall service for Linux that allows you to manage firewall rules at runtime. It provides a more flexible and powerful interface compared to ufw
, making it easier to manage complex firewall configurations.
Install firewalld on Your System
To use firewalld
, you need to install it first. You can do this using your package manager. For example, on AlmaLinux 9, you can use the following command:
sudo yum install firewalld
Enabling firewalld
After installing firewalld
, you need to enable it to start on boot and manage firewall rules dynamically.
sudo systemctl enable firewalld
Managing Docker Container Firewall Configuration with firewalld
firewalld provides comprehensive instructions for managing Docker container firewall settings. You can access these detailed instructions at this link.
First you need to disable iptables in docker by adding this line in your Docker daemon configuration file (/etc/docker/daemon.json
):
{
"iptables": false
}
After making changes, you need to reboot your host for the new firewall configurations to take effect. Restarting Docker alone won’t completely remove all existing iptables rules.
Since we disabled iptables in Docker, it’s no longer possible for containers to access the internet. To resolve this problem, you should add a new policy allowing Docker traffic to the internet. You can do this by running the following command:
# The --add-source option with Docker defaults to the network range 172.17.0.1/16.
firewall-cmd --permanent --zone docker --add-source 172.17.0.1/16
# Add a new policy allowing Docker traffic to the internet
firewall-cmd --permanent --new-policy dockerToWorld
firewall-cmd --permanent --policy dockerToWorld --add-ingress-zone docker
firewall-cmd --permanent --policy dockerToWorld --add-egress-zone ANY
firewall-cmd --permanent --policy dockerToWorld --set-target ACCEPT
firewall-cmd --permanent --policy dockerToWorld --add-masquerade
firewall-cmd --reload
Since Docker doesn’t use iptables to publish ports anymore, it’s ignored. Ports must be exposed through firewalld. To resolve this problem, you should add a new policy to allow external access to the container. You can do this by running the following command:
# Add a new policy allowing external access to the container
firewall-cmd --permanent --new-policy dockerFwdPort
firewall-cmd --permanent --policy dockerFwdPort --add-ingress-zone ANY
firewall-cmd --permanent --policy dockerFwdPort --add-egress-zone HOST
firewall-cmd --reload
To add port forwarding (equivalent of docker –publish) to a specific container use --add-forward-port
in the dockerFwdPort
policy. This example forwards port 8080
to port 80
. Note that the containers IP address must be known.
# Add a port forwarding rule to the dockerFwdPort policy
firewall-cmd --permanent --policy dockerFwdPort --add-forward-port port=8080:proto=tcp:toport=80:toaddr=172.17.0.2
firewall-cmd --reload