allow port 22 through the docker-user allowlist
the DOCKER-USER chain is the only thing gating docker-published ports from the internet — docker writes its own DNAT/FORWARD rules and bypasses ufw, so `ufw allow <port>` has no effect on a published container port. the allowlist permitted only 80 and 443, so a machine provisioned from this template dropped gitea ssh silently. the failure is hard to spot: the port looks open locally and docker ps shows it published, but external clients hang at TCP connect with no refusal. local tests pass because they arrive via lo and match the loopback RETURN before reaching the DROP. comments added so the next person recognises it faster. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,8 +2,18 @@
|
|||||||
# Append these to /etc/ufw/after.rules (after the existing COMMIT)
|
# Append these to /etc/ufw/after.rules (after the existing COMMIT)
|
||||||
# Blocks all external access to Docker-published ports except:
|
# Blocks all external access to Docker-published ports except:
|
||||||
# - Trusted IPs (add your own)
|
# - Trusted IPs (add your own)
|
||||||
# - Explicitly allowed public ports (80, 443)
|
# - Explicitly allowed public ports (80, 443, 22)
|
||||||
# - Docker internal and loopback traffic
|
# - Docker internal and loopback traffic
|
||||||
|
#
|
||||||
|
# This chain is the ONLY thing gating Docker-published ports from the internet:
|
||||||
|
# Docker writes its own DNAT/FORWARD rules and bypasses ufw entirely, so a
|
||||||
|
# `ufw allow <port>` has no effect on a published container port. If a container
|
||||||
|
# port must be reachable publicly, it needs a RETURN line below.
|
||||||
|
#
|
||||||
|
# Failure mode to recognise: the port appears open locally and `docker ps` shows
|
||||||
|
# it published, but external clients hang at TCP connect with no refusal. Local
|
||||||
|
# tests pass because they arrive via `lo` and match the loopback RETURN above,
|
||||||
|
# never reaching the DROP. Test from another machine, not from the host itself.
|
||||||
|
|
||||||
*filter
|
*filter
|
||||||
:DOCKER-USER - [0:0]
|
:DOCKER-USER - [0:0]
|
||||||
@@ -23,6 +33,9 @@
|
|||||||
# Allow public ports
|
# Allow public ports
|
||||||
-A DOCKER-USER -i eth0 -p tcp --dport 80 -j RETURN
|
-A DOCKER-USER -i eth0 -p tcp --dport 80 -j RETURN
|
||||||
-A DOCKER-USER -i eth0 -p tcp --dport 443 -j RETURN
|
-A DOCKER-USER -i eth0 -p tcp --dport 443 -j RETURN
|
||||||
|
# gitea SSH (NPM stream -> gitea:22). Host sshd does not use :22 publicly on a
|
||||||
|
# box that serves gitea — it moves to :2022 plus the tailnet IP, see ssh.socket.
|
||||||
|
-A DOCKER-USER -i eth0 -p tcp --dport 22 -j RETURN
|
||||||
|
|
||||||
# Drop everything else from external
|
# Drop everything else from external
|
||||||
-A DOCKER-USER -i eth0 -j DROP
|
-A DOCKER-USER -i eth0 -j DROP
|
||||||
|
|||||||
Reference in New Issue
Block a user