Skip Navigation

Docker security

You're probably already aware of this, but if you run Docker on linux and use ufw or firewalld - it will bypass all your firewall rules. It doesn't matter what your defaults are or how strict you are about opening ports; Docker has free reign to send and receive from the host as it pleases.

If you are good at manipulating iptables there is a way around this, but it also affects outgoing traffic and could interfere with the bridge. Unless you're a pointy head with a fetish for iptables this will be a world of pain, so isn't really a solution.

There is a tool called ufw-docker that mitigates this by manipulating iptables for you. I was happy with this as a solution and it used to work well on my rig, but for some unknown reason its no-longer working and Docker is back to doing its own thing.

Am I missing an obvious solution here?

It seems odd for a popular tool like Docker - that is also used by enterprise - not to have a pain-free way around this.

48 comments
  • How I sleep knowing Fedora + podman actually uses safe firewalld zones out of box instead of expecting the user to hack around with the clown show that is ufw.

    I could be wrong here but I feel like the answer is in the docs itself:

    If you are running Docker with the iptables or ip6tables options set to true, and firewalld is enabled on your system, in addition to its usual iptables or nftables rules, Docker creates a firewalld zone called docker, with target ACCEPT.

    All bridge network interfaces created by Docker (for example, docker0) are inserted into the docker zone.

    Docker also creates a forwarding policy called docker-forwarding that allows forwarding from ANY zone to the docker zone.

    Modify the zone to your security needs? Or does Docker reset the zone rules ever startup? If this is the same as podman, the docker zone should actually accept traffic from your public zone which has your physical NIC, which would mean you don't have to do anything since public default is to DROP.

  • If there's a port you want accessible from the host/other containers but not beyond the host, consider using the expose directive instead of ports. As an added bonus, you don't need to come up with arbitrary ports to assign on the host for every container with a shared port.

    IMO it's more intuitive to connect to a service via container_name:443 instead of localhost:8443

  • So, this discussion has intrigued me and some good points have been brought up by seemingly knowledgeable network engineers of which I am not. If I may, introduce you guys to my network to see if there are points I can improve on.

    For simplicity, the network diagram would be: modem---->stand alone pfsense firewall with a tailscale overlay, running Suricata, pfblockerng, vlans to segment server traffic from normal traffic, & a very robust rule set & ntopng for traffic analysis -----> server & devices. Server is piped through Cloudflare Tunnel/Zero Trust. On the server, I run UFW, fail2ban with a hair trigger & Crowdsec. Also, since I am the only user, I lock everything down in the .host Allow/Deny & use ssh keys. Users cause complexities and complexities turn into issues. All devices are running a VPN. I do run Docker in lieu of Podman. Server has been hardened through various means and to an extent in line with Lynis.

    I've been told that this is overengineered, but it seems to work just jammy. Knock on wood, I've never had a breach on my local network, though there is always the possibility. A long time ago, when I stood my first server up on a VPS, it got hacked almost immediately. So I dropped back and did some studying, but I am no network engineer.

    Anyways, for the experts here, my question is: What would you do to improve, harden, rip out, redo, add etc?

    ETA: Server also has a tailscale overlay.

  • If you are good at manipulating iptables there is a way around this

    Modern systems shouldn't be using iptables any more.

48 comments