Docker and FW4 (nftables) and access to containers

Hello all,
I'm currently testing Docker on OpenWrt running 22.03.5 as well as a recent snapshot of 23.x.

I'm running a reverse proxy (Traefik) connected to a dedicated docker network using the bridge driver (but not the default bridge) which listens on several ports but mainly 443 and 80 amongst others.

I cannot access any container including Traefik itself on port 443. I read somewhere that Docker has an issue with nftables and works through iptables-zzz-legacy which I've got installed. I also read here about using "iptables-nft ip6tables-nft" which I have also installed and reinstalled dockerd to no avail.

I don't have much experience with iptables but if I add "iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 443" I am able to connect to the container but that doesn't work for port 80 as the container that is being reverse-proxied-to is also running on port 80. The expectation is that traffic would hit the reverse proxy which in turn would connect to the other container that is listening on port 80 in another network but adding "iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 80" results, understandably, in endless redirects.

I don't really understand how the above rule works to be honest. I'm interpreting it as when packets arrive to the NAT table via the prerouting chain using the TCP protocol on destination port 443 then redirect that packet to port 443 which to my mind should result in an endless loop because that's where the traffic arrived anyway but I'm still learning :slight_smile:

Please help.

1 Like

Following as I have the same version of OpenWrt with the same issue at the moment. No container access from LAN on bridge network or custom bridge network.

The expectation is that traffic would hit the reverse proxy which in turn would connect to the other container that is listening on port 80 in another

You could run the container on another port than 80 as a workaround eg: 8080.

iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

edit: spelling

Thank you @bigsmile. I don't think it's possible to change this for the specific container that I'm using. However, I think the issue is something to do with making docker accessible from the LAN in general.
I've searched the forum and found some confusing posts some discussing compatibility issues, some appear to be discussing potential bugs and others with workarounds. I can't find a more recent working solution to allow traffic from the LAN to the Docker containers hence the post.

It would be great if someone could explain or point me in the direction of an article that explains the default docker interface and zone which I believe have something to do with this but I can't see the relation between what is created at the OpenWrt network level and the docker bridge and user created networks

I haven't done anything with docker, but you could run tcpdump on the router to see where it goes astray.

hi,

do you run luci? because if so it will clash with docker-proxy, which would direct your "external" traffic into your traefik container but will not able.

you don't need to deal with firewall rules at all, below compose file brings things up nicely and can access whoami.docker.localhost


cat traefik.yaml
version: '3'

services:
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:latest
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
  whoami:
    # A container that exposes an API to show its IP address
    image: traefik/whoami
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"

curl -H Host:whoami.docker.localhost http://<ip of router hosting traefik> gives back stuff like.


Hostname: 337915f2b2f3
IP: 127.0.0.1
IP: 172.18.0.3
RemoteAddr: 172.18.0.2:56008
GET / HTTP/1.1
Host: whoami.docker.localhost
...

I am indeed running Luci but I changed the uhttpd port to 9443 and it's working fine. Are you saying that the Luci process would still interfere somehow?

In your example yaml file, your container is using the default bridge. My set up uses two separate networks for isolation.

uhttpd by default using http port 80 and https port 443, so based on

I guess maybe uhttpd still listening on port 80. but with below it seems to work too (i.e. using non-default network):

$ docker network create proxy
$ cat traefik.yaml
version: '3'

services:
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:latest
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - proxy
  whoami:
    # A container that exposes an API to show its IP address
    image: traefik/whoami
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
    networks:
      - proxy

networks:
  proxy:
    external: true

$ curl -H Host:whoami.docker.localhost http://127.0.0.1
Hostname: f739133b8373
IP: 127.0.0.1
IP: 172.20.0.3
RemoteAddr: 172.20.0.2:43164
GET / HTTP/1.1
Host: whoami.docker.localhost

Apologies. I should have mentioned that I changed uhttpd port 80 to 82.

I will give it a try with your yaml and let you know. Thank you so much.

Hi all,
I managed to resolve the issues I've been having.

With regards to the LAN to Docker containers access:
I edited the "Docker" zone under Firewall and added the "br-*" devices to the "Covered devices" list under Advanced Settings.

To allow the containers access out to the Internet, I added a new zone under Firewall. Called it docker_wan. Set Input and Forward to "Reject" and left Output set to "Accept". Then under Advanced Settings I added the "br-" interface that the containers are connected to to the list of "Covered Devices".

EDIT:
You must also add Traffic Rules to allow traffic on the relevant ports i.e. 443, 53 etc from the LAN to the Docker zones

I hope this helps someone in the future.

Thanks to everyone who assisted :slight_smile:

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.