Using iptables to block internet access from containers doesn't work. Running docker as rootless

I’m trying to block internet access from my containers with iptables but it just doesn’t work.

I defined the network with a compose file like this:

networks:
    no-internet:
        ipam:
            config:
                - subnet: 172.19.0.0/16
                  gateway: 172.19.0.1

Then i make the iptables rules:

sudo iptables --insert DOCKER-USER -s 172.19.0.0/16 -j REJECT --reject-with icmp-port-unreachable
sudo iptables --insert DOCKER-USER -s 172.19.0.0/16 -m state --state RELATED,ESTABLISHED -j RETURN
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Then i restart docker daemon with: systemctl restart docker

But the containers can still access internet even after i reboot.

This worked fine for me on my old system where i used PopOS.
In my new system i use PikaOS and i also run docker as rootless.

My goal is this:
I want the container to be able to communicate with the host but not with the internet.

How can i make this work?

Hello!
Rootless Docker doesn’t use the host’s iptables, so your DOCKER-USER rules never apply. To block internet while allowing host communication, either switch back to rootful Docker or create an internal: true network in Compose, which isolates containers from the internet but still lets them talk to the host.

Hello!
Ok i see, that’s why it is not working.

You mean like this?

networks:
    no-internet:
        internal: true
        ipam:
            config:
                - subnet: 172.19.0.0/16
                  gateway: 172.19.0.1

That’s not working though as containers in an internal network cannot communicate with the host. Only with other containers on the same network.

You probably replied to an AI, so I would not expect many new replies, but when using a rootless Docker, the Docker daemon is isolated and has its own network namespace, so even communicating with the host is tricky as far as I remember, depending on the network driver chosen for rootless kit.

If you want to access a container port from the outside through a web browser, but you don’t want to allow the container to have internet access, you could use a solution that I made for Docker Desktop, but a rootless Docker is similar. You can run a web browser in a container to access another container that has only an “internal” network without internet access. You can still acesss the webbrowser container, because that has a public docker network.

https://dev.to/rimelek/docker-network-and-network-namespaces-in-practice-5h9#running-a-web-browser-in-a-net-namespace-in-a-vm-docker-desktop

I tested it with rootless Docker now.

This web browser is just one tool that you can use if you want, but the proxy also forward the request directly to the app container instead of a web-based remote desktop, so you could use curl from the host to acess an API for example, but the app container would not be able to send requests to the internet, only to the proxy container, which would not forward it to the internet.

If you want communication from the container to the host only, I never tried it, but my first idea is what I wrote for using host.docker.internal with Docker CE. I would probbaly try to use another container on an internal network s a poxy for the outside world which forwards requests to a unix socket. Another container would run on the host network which would only forward the requests coming through the socket to the actual host’s loopback IP on a specific port.

https://forums.docker.com/t/host-docker-internal-in-production-environment/137507/4?u=rimelek