I'm running Uptime Kuma in Docker with the host port bound only to localhost: 127.0.0.1:3005 -> 3001/tcp. I want the service to remain inaccessible from the public network and only reach it through an SSH tunnel. I tried using `ssh -L 3005:127.0.0.1:3005 user@server -p -vv`, but a default-drop iptables policy prevented the connection. Loopback traffic was allowed, but I wasn't sure whether the issue involved the OUTPUT, FORWARD, or Docker NAT chains. Since Docker translates the connection from the host port 3005 to the container port 3001, what firewall rule or tunnel configuration is appropriate?
2 Answers
Because the port is published on the host as `127.0.0.1:3005`, the SSH tunnel should target the host-side port: `ssh -L 3005:127.0.0.1:3005 user@server -p `. You then open `http://127.0.0.1:3005` on your local machine. You normally should not target the container port 3001 from the SSH client, since that port exists inside Docker’s network namespace.
Binding the published port to `127.0.0.1` is the right way to keep the service off the public interface. You can verify the behavior with `ss -lntp` and Docker’s port listing, then test the tunnel from the client. Firewall rules should account for the actual post-NAT interface and port, while connection tracking should handle the return packets.

That matches the intended setup: Docker listens only on the server’s loopback address, while SSH forwards my local port to that host-side listener.