9000/tcp ExampleProgram Now …" /> 9000/tcp ExampleProgram Now …"/> /home/adam-ant – A Note about using UFW with Docker

A Note about using UFW with Docker

Posted on Sun 06 August 2017 in Linux

UFW is a great program. It allows easy configuration of a powerful firewall, without the need to learn IPTables and the large amount of networking knowledge that goes with it.
However, when used with Docker, there is something you need to be aware of - UFW lies!

Although UFW makes changes to IPTables, it does not read back the same route tables it modifies. This means that a program that works directly with IPTables, such as Docker, could make rules that go against what you are trying to do with UFW.

For example, let's take a standard web server configuration: allow traffic on ports 22, 80 and 443. The output of UFW is as follows:

adam@ExampleHost:~$ 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                  
443/tcp                    ALLOW IN    Anywhere                  
80/tcp                     ALLOW IN    Anywhere 

Now let's load up a Docker container that exposes port 8765 to the outside world:

adam@ExampleHost:~$ docker ps
CONTAINER ID        IMAGE                   COMMAND        CREATED             STATUS          PORTS                     NAMES
f9955df5766f        example/example         "/bin/sh"      3 minutes ago       Up 1 hours      0.0.0.0:8765->9000/tcp    ExampleProgram

Now in theory, despite this program being bound to the outside world through Docker, our firewall should block them right?

However, you will find that's not the case. The application will be allowed out through the firewall, despite UFW still looking like it does above.

The reason for this is Docker modifies the IPTables rule set directly to give containers networking. This means it effectively bypasses UFW, as it works on the same rules table that UFW does, rather than under them.

What can we do about this?

Theres a few things you can do to sort this: Bind on the loopback interface for everything: This allows services to communicate locally, without exposing them to the world Never use the -p (or -P) flags on anything you don't want to be public - even if secure content is hosted on a seperate port. * Run the Docker daemon with --iptables=false. This has it's own networking issues - only use it if you are aware of the risks!