Introduction
UFW or Uncomplicated Firewall is a simplified CLI firewall management tool. It is easy to use since it hide the complexity of iptables. It is also easy to configure since it has a simple syntax and suitable for controlling firewall from shell scripts. UFW can be used to allow or deny connections based on various criteria, such as source and destination IP addresses, ports, and protocols.
The problem is when we install Docker, it will install two custom chains in the iptables: DOCKER
and DOCKER-USER
. It
ensure all incoming packets are always checked by these chains first. In orther words, Docker will bypass all the
rules that we set in the ufw
chain and our published ports can be accessed from anywhere.
To overcome this problem, we can disable docker’s iptables rules configuration option by adding the --iptables=false
to the docker daemon but this also means that we have to give up docker’s network management system which is a big deal.
All containers can not access the external network anymore!
We can maintain the iptables by manually add rules but it is a tedious task and not recommended since it requires a lot
of knowledge about iptables. This is not what we want and here is where ufw-docker
comes in.
UFW-Docker is an open source solution for securely using Docker and UFW together. It provides a framework for managing UFW rules and allows users to create their own sets of rules by combining existing rules. It also provides a way to ensure that Docker containers are running securely while still allowing access to the ports that they need.
Now let’s get started with UFW first to understand how it works and then we will move on to UFW-Docker.
ufw
Ufw should be installed by default on Ubuntu systems. If not, you can install it with:
sudo apt install ufw
By default, ufw is disabled. Just to make sure, you can check the status with:
sudo ufw status
It should return:
Status: inactive
Now let’s block all incoming traffic.
sudo ufw default deny incoming
Now if we enable the firewall, all incoming traffic will be blocked. But be mindful that if you’re using ssh, you will not be able to access the server anymore. So let’s allow ssh first.
sudo ufw allow ssh
In some cases, you may want to allow http and https ports as well.
sudo ufw allow http
sudo ufw allow https
Now we can safely enable the firewall.
sudo ufw enable
Let’s check the status again. Now with extra verbose
flag.
sudo ufw status verbose
It should return:
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
You definitely will want to delete some rules later. So let’s take a look at the rule numbers. Basically the same output as above prefixed with rule numbers.
sudo ufw status numbered
To delete a rule, you can use the following command substituting the rule number with the one you want to delete.
sudo ufw delete <rule number>
Ufw allows you to specify a port and an IP address to allow incoming traffic to. This is useful if you want to allow incoming traffic to a specific port from a specific IP address.
sudo ufw route allow from $EXTERNAL_IP to $CONTAINER_IP port <port> comment "allow from $EXTERNAL_IP to $CONTAINER_IP"
ufw-docker
By now you should have a basic understanding of how ufw works. Now let’s move on to ufw-docker. First, we need to install it.
sudo wget -O /usr/local/bin/ufw-docker \
https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
ufw-docker needs to modify the configuration rules after.rules
file in /etc/ufw/
directory. Please refer to their
Github repo for more details.
sudo ufw enable
sudo ufw-docker install
sudo systemctl restart ufw
Now let’s expose a port for a container. Note that we don’t need to expose the port to our host machine. We only need to expose it to the docker network. The iptables rules will route the traffic to the container.
sudo ufw-docker allow nginx
Here nginx
is the name of the container. This will essentially allow all incoming traffic to port 80 and 443 of the
container nginx
but it only works if the container is running under docker network. If your container is running with
network-mode: host
, you can use ufw allow
instead. (Not recommended)
And to remove it, you can use the following command.
sudo ufw-docker remove nginx
You can also specify a port to remove.
sudo ufw-docker remove nginx 80
And that should get you started with UFW and Docker networking!
Conclusion
As you can see, Docker networking is a powerful tool that allows you to create isolated networks for your containers. In this article, I showed how to configure it using UFW since it’s the most popular firewall among Ubuntu users. If you are using other operating systems like Debian or CentOS, there are similar tools available for them as well. If you have any questions or comments, feel free to leave them below.