Docker UFW Security Flaw

I am running a number of docker containers on my Manjaro system on which I also use UFW to manage the firewall rules.

I recently became aware that docker containers were exposed regardless of the UFW configuration causing a major security hole.

The problem is described here along with a supposed solution.

Unfortunately, after installing it I have found that it has made no difference. Most posts I have found about the script are from Debian/Ubuntu users.

Have any other Manjaro users come across this Docker security issue and fixed it with ufw-docker or something else?

It is not a bug it’s a feature.

When opening ports, you should always only open them for 127.0.0.1 and not globally.

The DOCKER_USER chain is run before, so you can add rules there to block.

What if you want a port to be exposed to some sources other than localhost. Surely UFW should allow you to have rules for specific hosts/ranges. Currently, exposing in docker exposes them completely and UFW is ignored.

That’s definitely a bug, or perhaps the Docker design flaw to not include external firewall support.

That doesn’t make sense. By design, Docker container lives withing the local system virtual private network and can be exposed to the external world via the host physical port.

Docker manages its own iptables rules. This is how docker works.

However Docker can work together with firewalld. Maybe it is time to switch to a supported firewall solution for docker.

1 Like

Exactly, and when you forward the host port to your container, the host port will be accessible.

I see what you meant here.

But this is confusing:

You already open them globally, and anyone can access the respective socket.

Well as @xabbu highlighted, you can only use the supported firewall by Docker. You’ll probably need to use the not-easy-to-use iptables. That’s just the Docker firewall design for now; it lacks external firewall support like UFW.

No, that’s not the case. If you use -p 8000:8000 then on your host, you globally exposed port 8000 for any access. So, you should either not forward the port in the first place, or only for the host: -p 127.0.0.1:8000:8000.

If you have it open in the first case, you must use iptables and modify the DOCKER_USER chain.

I have tested firewalld and can confirm it works exactly as expected.
Using firewalld I can control access to the ports exposed by docker.
Time to migrate from UFW to firewalld.
Thanks for the tip @xabbu .

I spoke too soon. When I restarted docker it started interfering again.

As the documentation from Docker says firewalld is supported, hopefully this will get fixed.

You can disable docker messing iptables rules

Edit/create /etc/docker/daemon.json with the following content:

{
  "iptables": false
}

Next to that, if you really don’t want to expose a port from your container, do as @mithrial already wrote and only bind the port to the hosts loop-back interface instead off all interfaces:

-p 127.0.0.1:1234:80 instead of
-p 1234:80 or -p 0.0.0.0:1234:80

I agree, the default docker config is pretty ugly though.

I had already tried the daemon.log edit but it broke things.

It seems if you delete the zone created by docker (called docker) things start to behave as expected.
Every time docker restarts it recreates the zone so I have created a file /etc/systemd/system/docker.service.d/overide.conf

[Service]
ExecStartPost=firewall-cmd --permanent --delete-zone=docker
ExecStartPost=firewall-cmd --reload

So far this seems to be working. Bit of a fudge though.