ConfigClarity

Free browser-based DevOps audit tools โ€” no signup, nothing leaves your browser

Docker UFW bypass

Docker opens ports past your firewall โ€” here are 3 permanent fixes

This affects every Docker installation on Ubuntu/Debian with UFW. If you have any ports: mapping in docker-compose.yml, those ports are likely publicly accessible.

Why this happens

UFW manages the INPUT chain in iptables. Docker writes to the DOCKER chain in the nat table's PREROUTING chain. PREROUTING executes before INPUT โ€” so Docker's rules run before UFW ever sees the packet.

Fix 1 โ€” Bind to 127.0.0.1 (recommended)

The cleanest solution. Adds 127.0.0.1: prefix to all ports that shouldn't be publicly accessible.

ports:
  - "127.0.0.1:6379:6379"   # Redis โ€” localhost only
  - "127.0.0.1:5432:5432"   # Postgres โ€” localhost only
  - "80:80"                  # nginx โ€” intentionally public
  - "443:443"                # nginx โ€” intentionally public

Fix 2 โ€” Use the DOCKER-USER chain

Docker checks the DOCKER-USER chain before processing. Rules here apply to all Docker traffic.

# Block external access to port 6379, allow localhost
sudo iptables -I DOCKER-USER -p tcp --dport 6379 ! -s 127.0.0.1 -j DROP

# Make persistent across reboots
sudo apt install iptables-persistent
sudo netfilter-persistent save

Fix 3 โ€” Disable Docker iptables (advanced)

# /etc/docker/daemon.json
{
  "iptables": false
}
# Then restart Docker and configure NAT manually
sudo systemctl restart docker
Warning: Disabling iptables breaks internet access for containers. Only use this if you're manually managing all routing rules.

Audit all Docker port bindings

Paste your docker-compose.yml and the Docker Auditor flags every 0.0.0.0 binding with the 127.0.0.1 fix.

Open Docker Auditor โ†’

Frequently Asked Questions

Does Hetzner/DigitalOcean's cloud firewall protect me from this?

Cloud firewalls operate at the network level before traffic reaches your server. They can block Docker-exposed ports. However, relying solely on a cloud firewall is fragile โ€” one misconfiguration and you're exposed. Defence in depth: use both a cloud firewall and the 127.0.0.1 binding approach.

My app needs to access the database from the host โ€” can I still use 127.0.0.1 binding?

Yes. 127.0.0.1:5432:5432 means the port is accessible from the host machine on localhost. You can still connect with psql -h 127.0.0.1 -p 5432 from the host. It only blocks external network access.

Related Glossary Terms