Skip to content

Instantly share code, notes, and snippets.

@goll
Last active December 13, 2024 22:04
Show Gist options
  • Save goll/bdd6b43c2023f82d15729e9b0067de60 to your computer and use it in GitHub Desktop.
Save goll/bdd6b43c2023f82d15729e9b0067de60 to your computer and use it in GitHub Desktop.
Docker nftables configuration for Debian 10

Not happy with Docker modifying your precious firewall rules?

Prerequisites

Install Docker CE and nftables:

$ sudo apt-get install nftables
$ sudo systemctl --now enable nftables

Installing

Manually (create/modify daemon.json before starting docker.service):

$ sudo systemctl start docker
$ sudo systemctl stop docker containerd
$ sudo iptables-save > iptables-docker.conf
$ sudo iptables-restore-translate -f iptable-docker.conf > docker.nft
$ sudo nft flush ruleset
$ sudo nft -f docker.nft
$ sudo nft -s list ruleset > /etc/nftables-docker.conf

tl;dr

$ curl -fsSLO https://gist.github.com/goll/bdd6b43c2023f82d15729e9b0067de60/raw/nftables-docker.sh
$ sudo bash -x nftables-docker.sh

For a persistent config just overwrite /etc/nftables.conf with /etc/nftables-docker.conf

If you prefer manual start/stop you can create an alias for example:

alias dock-on='sudo nft -f /etc/nftables-docker.conf && sudo systemctl start docker'
alias dock-off='sudo systemctl stop docker containerd && sudo nft -f /etc/nftables.conf && sudo ip l d docker0'
table ip filter {
chain INPUT {
type filter hook input priority 0; policy accept;
}
chain FORWARD {
type filter hook forward priority 0; policy accept;
counter jump DOCKER-USER
counter jump DOCKER-ISOLATION-STAGE-1
oifname "docker0" ct state established,related counter accept
oifname "docker0" counter jump DOCKER
iifname "docker0" oifname != "docker0" counter accept
iifname "docker0" oifname "docker0" counter accept
}
chain OUTPUT {
type filter hook output priority 0; policy accept;
}
chain DOCKER {
}
chain DOCKER-ISOLATION-STAGE-1 {
iifname "docker0" oifname != "docker0" counter jump DOCKER-ISOLATION-STAGE-2
counter return
}
chain DOCKER-ISOLATION-STAGE-2 {
oifname "docker0" counter drop
counter return
}
chain DOCKER-USER {
counter return
}
}
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
fib daddr type local counter jump DOCKER
}
chain INPUT {
type nat hook input priority 100; policy accept;
}
chain POSTROUTING {
type nat hook postrouting priority 100; policy accept;
oifname != "docker0" ip saddr 172.17.0.0/16 counter masquerade
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
ip daddr != 127.0.0.0/8 fib daddr type local counter jump DOCKER
}
chain DOCKER {
iifname "docker0" counter return
}
}
#!/bin/bash
systemctl stop docker containerd
tee /etc/docker/daemon.json << EOF
{
"iptables": false
}
EOF
curl -fsSLO https://gist.github.com/goll/bdd6b43c2023f82d15729e9b0067de60/raw/nftables-docker.conf -o /etc/nftables-docker.conf && nft -f /etc/nftables-docker.conf
systemctl start docker
@fabienengels
Copy link

So you manage your exposed ports manually ?

@obarisk
Copy link

obarisk commented May 16, 2021

If expored by docker-proxy, this ruleset work well. Without docker-proxy, it requies dnat.

@CRAG666
Copy link

CRAG666 commented Mar 2, 2022

I followed the entire tutorial to the letter and I have problems connecting to the internet from the container

@TimB87
Copy link

TimB87 commented Mar 6, 2022

This works for me on CRUX, thanks for sharing!

@CRAG666
Copy link

CRAG666 commented May 24, 2022

@goll I also have problems connecting from localhost, When I use Docker Compose

@ukd1
Copy link

ukd1 commented Aug 5, 2022

Thanks for this!

@mihaigalos
Copy link

This worked for me after a restart of the system, not before. I suspect it's because the docker socket that got recreated.

@zmitya
Copy link

zmitya commented Mar 15, 2023

It is very strange, because Docker sets up its FORWARD chain's policy as "drop" (for a reason). But in your case it is accept for some reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment