UFW blocks cloning over ssh from selfhosted forgejo

Hi there,

been running my own Forgejo instance for a while now, but can’t quite get cloning over ssh to work.

Forgejo is running via docker compose (docker-compose file is this one: Installation with Docker | Forgejo – Beyond coding. We forge. , unmodified beyond adding it to the network of my caddy instance).

I have ufw set up and unblocked port 222 with ufw route allow proto tcp from any to any port 222.

ssh anathema -p 222 hangs forever (anathema is the name of that server in my ssh config, don’t ask)
ssh localhost -p 222 on the server immediately fails with Permission denied (publickey). (as expected).
Regular ssh over port 22 works perfectly, just the forgejo ssh breaks, I assume this is somewhat related to running in docker.

ufw 0.36.2
Docker version 29.8.1

Happy to provide more info as needed.

IIRC there’s a bit of an ordering issue here.

For non-local traffic, ports are exposed using DNAT rules, so they go through the forward chain with the substituted address and port.

Try

ufw route allow out on CONTAINERBRIDGE proto tcp from any to CONTAINERIP port 22

If that doesn’t work could you post the output of

iptables -t nat -vL
and
iptables -t filter -vL

1 Like

Alright, that works, thanks a lot :heart:

Pardon my lacking understanding of Linux networking, so do I understand correctly that the traffic takes this route:
The outer world -> eth0:222 -> docker0 -> forgejo:22 (eth0 being the outbound interface & docker0 being the network interface docker creates)
So docker0 -> forgejo:22 is where it gets blocked, because it’s an outbound packet, but not from localhost technically?
localhost -> eth0:222 -> docker0 -> forgejo:22 works, because while it takes the same path it’s coming from localhost?
Really out of my depth here tbh :sweat_smile:

So if I understand this correctly ufw route allow out on docker 0 from any to any would be safe, because nothing can get to docker0 without going through eth0, so I have to whitelist 222 regardless in my case?

Is sshd listening on port 222? If it works on 22, it’s probably listening on port 22. Open up sshd_config (usually in /etc/ssh/sshd_config) and see what the port is set to. By default it’s set to 22, but commented out (so it falls back to 22 which is the default). Uncomment that line, add a 2 on the end, and it should work.

1 Like

I recommend you read the whole post & subsequent conversation before posting, this isn’t really megathread-amounts of text :smiley:

  1. The original issue has already been solved as stated in the message above, I just forgot to mark it as the solution.
  2. I have already stated in the original post that I can reach the ssh server in question on the server itself through localhost port 222.
1 Like