Hello and thanks for reading!
I can not reach a created portainer container. While troubleshooting I came across some weird things that I want to share here.
My question: does anyone have an idea or even know how I can get to the container without opening my firewall completely? Thanks in advance. i din’t understand why a standard Docker Ruleset kills the connection itself. Thx for help.
—| What happened |—
I created a volume and a Portainer container with the following command, reachable on Port 9443
and Port 8000
:
sudo docker volume create portainer_data
sudo docker run -d -p 8000:8000 -p 9443:9443 --name portainer -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data cr .portainer.io/portainer.io/portainer/portainer-ce:latest
Unfortunately, I did not reach the container from another machine (https://192.168.1.129:9443
). The 129
address is the static IP of the host where Docker is running.
I then looked more closely at firewall rules (nftables
) and the firewall rules that Docker sets itself. I noticed that if I delete the Docker firewall settings, the container is reachable on Port 9443
. I did this by restarting the firewall (sudo sytsemctl restart nftables.service
) , which causes flush ruleset from /etc/nftables.conf
to be executed as the first statement.
My firewall ruleset is small, stateful and simple (The logic from the Docker host’s point of view):
- accept SSH/22 requests from outside.
- receive already existing sessions
- you are allowed to make all requests to the outside
- answers/requests from existing sessions are accepted
—| Ressources (Screenshots, Configs, Commands) |—
Environment: Raspberry Pi 3B+
OS: Raspberry Pi OS (64Bit) lite
OS Version (lsb_release -a)
:
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye
Docker Version (sudo docker version
):
Client: Docker Engine - Community
Version: 23.0.1
API version: 1.42
Go version: go1.19.5
Git commit: a5ee5b1
Built: Thu Feb 9 19:46:41 2023
OS/Arch: linux/arm64
Context: default
Server: Docker Engine - Community
Engine:
Version: 23.0.1
API version: 1.42 (minimum version 1.12)
Go version: go1.19.5
Git commit: bc3805a
Built: Thu Feb 9 19:46:41 2023
OS/Arch: linux/arm64
Experimental: false
containerd:
Version: 1.6.18
GitCommit: 2456e983eb9e37e47538f59ea18f2043c9a73640
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Docker installation over sudo curl -fsSL http s://get.docker.com -o get-docker.sh | sudo chmod+x | sudo get-docker.sh
— — — —
Command Strings to create the Container
sudo docker volume create portainer_data
sudo docker run -d -p 8000:8000 -p 9443:9443 --name portainer -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data cr .portainer.io/portainer/portainer-ce:latest
— — — —
sudo nano /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state {established, related} accept
tcp dport 22 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
— — — —
sudo nft list ruleset
(before install Container Portainer)
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state { established, related } accept
tcp dport 22 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
table ip nat {
chain DOCKER {
iifname "docker0" counter packets 0 bytes 0 return
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 masquerade
}
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
fib daddr type local counter packets 1 bytes 52 jump DOCKER
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
ip daddr != 127.0.0.0/8 fib daddr type local counter packets 0 bytes 0 jump DOCKER
}
}
table ip filter {
chain DOCKER {
}
chain DOCKER-ISOLATION-STAGE-1 {
iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-2
counter packets 0 bytes 0 return
}
chain DOCKER-ISOLATION-STAGE-2 {
oifname "docker0" counter packets 0 bytes 0 drop
counter packets 0 bytes 0 return
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
counter packets 0 bytes 0 jump DOCKER-USER
counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-1
oifname "docker0" ct state related,established counter packets 0 bytes 0 accept
oifname "docker0" counter packets 0 bytes 0 jump DOCKER
iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 accept
iifname "docker0" oifname "docker0" counter packets 0 bytes 0 accept
}
chain DOCKER-USER {
counter packets 0 bytes 0 return
}
}
— — — —
sudo nft list ruleset
(after install Container Portainer)
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state { established, related } accept
tcp dport 22 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
table ip nat {
chain DOCKER {
iifname "docker0" counter packets 0 bytes 0 return
iifname != "docker0" meta l4proto tcp tcp dport 9443 counter packets 20 bytes 1040 dnat to 172.17.0.2:9443
iifname != "docker0" meta l4proto tcp tcp dport 8000 counter packets 0 bytes 0 dnat to 172.17.0.2:8000
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
oifname != "docker0" ip saddr 172.17.0.0/16 counter packets 0 bytes 0 masquerade
meta l4proto tcp ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 9443 counter packets 0 bytes 0 masquerade
meta l4proto tcp ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 8000 counter packets 0 bytes 0 masquerade
}
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
fib daddr type local counter packets 24 bytes 1248 jump DOCKER
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
ip daddr != 127.0.0.0/8 fib daddr type local counter packets 0 bytes 0 jump DOCKER
}
}
table ip filter {
chain DOCKER {
iifname != "docker0" oifname "docker0" meta l4proto tcp ip daddr 172.17.0.2 tcp dport 9443 counter packets 20 bytes 1040 accept
iifname != "docker0" oifname "docker0" meta l4proto tcp ip daddr 172.17.0.2 tcp dport 8000 counter packets 0 bytes 0 accept
}
chain DOCKER-ISOLATION-STAGE-1 {
iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-2
counter packets 20 bytes 1040 return
}
chain DOCKER-ISOLATION-STAGE-2 {
oifname "docker0" counter packets 0 bytes 0 drop
counter packets 0 bytes 0 return
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
counter packets 20 bytes 1040 jump DOCKER-USER
counter packets 20 bytes 1040 jump DOCKER-ISOLATION-STAGE-1
oifname "docker0" ct state related,established counter packets 0 bytes 0 accept
oifname "docker0" counter packets 20 bytes 1040 jump DOCKER
iifname "docker0" oifname != "docker0" counter packets 0 bytes 0 accept
iifname "docker0" oifname "docker0" counter packets 0 bytes 0 accept
}
chain DOCKER-USER {
counter packets 20 bytes 1040 return
}
}