2026-04-01 · UFWUbuntuDockerLinuxFirewall

UFW and nftables on Ubuntu 22.04: What Changed and Why It Breaks Docker

Ubuntu 22.04 quietly switched UFW to use nftables as its firewall backend. UFW commands still work exactly the same. But Docker still uses iptables — and now the two systems don't talk to each other at all, which makes the Docker UFW bypass problem worse, not better.

Ubuntu 22.04 changed UFW's default firewall backend from iptables to nftables. For most people this change is completely invisible — UFW still works the same way from the command line. But if you're running Docker, or if you're mixing UFW with other firewall tools, this change matters and can cause rules to stop working in confusing ways.

What changed in Ubuntu 22.04

Ubuntu 22.04 ships with nftables as the default kernel firewall backend. When you install UFW on Ubuntu 22.04, it uses nftables under the hood instead of iptables. The UFW commands you already know (ufw allow, ufw deny, ufw status) all work the same — but the rules they generate are now nftables rules, not iptables rules.

# Check which backend UFW is using:
sudo ufw status verbose
cat /etc/default/ufw | grep "IPTABLES_BACKEND"

# Check nftables rules directly:
sudo nft list ruleset

# Check iptables (will show nftables rules via compatibility layer):
sudo iptables -L

Why this breaks Docker

Docker has been using iptables for network management since the beginning. When Docker starts, it inserts rules into iptables chains — DOCKER, DOCKER-USER, DOCKER-ISOLATION-STAGE-1 — to manage container networking and port forwarding.

On Ubuntu 22.04, Docker still uses iptables even though UFW is now using nftables. This means Docker's rules and UFW's rules are in completely separate systems that don't interact with each other. UFW doesn't know about Docker's containers. Docker doesn't know about UFW's deny rules.

The result is the classic Docker UFW bypass: you add a UFW deny rule for a port, but the Docker container on that port is still accessible from the internet because Docker's iptables rules bypass UFW's nftables rules entirely.

# Verify Docker is still using iptables on Ubuntu 22.04:
sudo iptables -L DOCKER --line-numbers
# You'll see Docker's rules here even though UFW uses nftables

Check your current UFW backend

cat /etc/default/ufw

Look for IPT_SYSCTL and IPTABLES_BACKEND. On Ubuntu 22.04 you'll typically see the backend set to nftables or the file may not specify it explicitly (defaulting to nftables).

# Also check the actual active firewall:
sudo nft list tables
# If you see tables like "inet ufw6" — UFW is using nftables

sudo iptables -L INPUT | head -5
# If you see DOCKER chains — Docker is using iptables

The fix: bind Docker ports to localhost

The cleanest fix for the Docker/nftables conflict is to not expose Docker ports publicly in the first place. Bind all container ports to 127.0.0.1 and use Nginx or Traefik as a reverse proxy for public access.

# In docker-compose.yml — bind to localhost only:
services:
  myapp:
    ports:
      - "127.0.0.1:3000:3000"  # Only accessible locally
    # NOT: "3000:3000" — this binds to 0.0.0.0 and bypasses UFW

  db:
    ports:
      - "127.0.0.1:5432:5432"  # Database never public

With this setup, the container ports are only accessible via localhost. Nginx on port 80/443 (which UFW allows) proxies traffic to the container. Docker's iptables bypass becomes irrelevant because there's nothing public to bypass to.

Alternative: force Docker to use iptables compatibility mode

If you need Docker ports to be directly accessible and want UFW to control them, you can configure Docker to use iptables in a way that interacts better with nftables:

# /etc/docker/daemon.json:
{
  "iptables": true,
  "ip6tables": true
}

sudo systemctl restart docker

Note: Even with this setting, Docker's iptables rules and UFW's nftables rules operate in separate subsystems. The most reliable approach remains binding containers to 127.0.0.1 rather than relying on firewall rules to block container ports.

What about Ubuntu 20.04?

Ubuntu 20.04 uses iptables as the default backend. UFW and Docker both use iptables, so there's a different interaction — Docker's rules can actually interfere with UFW's rules in iptables. The Docker UFW bypass problem exists on both versions, just through different mechanisms.

# On Ubuntu 20.04 — check iptables backend:
sudo update-alternatives --display iptables
# Should show iptables-legacy or iptables-nft

Quick summary

Audit your UFW rules for Docker bypass risk, nftables conflicts, and missing default-deny on Ubuntu 22.04.

Open Firewall Auditor →

Related guides