SSH connection refused for External IP


When I SSH into my Rocky Linux server via internal IP (, it works fine. Via the external IP, (from Googling ‘what’s my ip’), it doesn’t work. I get a connection refused message. Pinging it with ping returns good packets, though.

I have also changed the port from default from 22 to 2021 following the guide here: Change the SSH Port in CentOS and Red Hat - which I also added the firewalld rule sudo firewall-cmd --add-port=2021/tcp --permanent. And again, using my custom port, everything is fine via internal IP.

External IP gives the following message:

ssh: connect to host xx.xx port 2021: Connection refused

If I use a random port like 2000, the message is instead Connection timed out.

I tried disabling firewalld and nftables and it didn’t seem to make a difference (via systemctl stop firewalld and systemctl stop nftables).

I also tried further edits to nano /etc/ssh/sshd_config (beyond changing port which worked internally) to the ListenAddress, by uncommenting it out and setting it and systemctl restart sshd as well as leaving it commented.

Any guidance is appreciated. It is a fresh install of Rocky Linux 9.2.

Did you set up a ssh tunnel through your cable modem? The link below is a tutorial for the modem software I use that is just an example of the steps needed. It will be different for you as I suppose your modem is provided by your isp and thus you will have to get access to their software to see whether you can open an ssh tunnel.
SSH tunnel

I haven’t done this myself.


I am not sure if such a service is available in the server network’s router and it seems quite complicated, I think you’re suggesting another layer of indirection to proxy into the server’s internal network?

Right now what I don’t understand with my approach is why it seems to recognise the port 2021 and refusing the connection but allowing it internally. I think it is listening and handling it but just refusing it when it’s not the internal IP, since for any other port it just resolves in a timeout. However this makes little sense as I also tried setting the firewalld cmd --add-port=2021/tcp with zone public.

Did you configure port forwarding (aka NAT) on the Internet gateway to forward SSH traffic to the server? Otherwise, your SSH connection will terminate at the gateway and it will throw the connection refuse message, because it doesn’t listen on that port.

1 Like

Where do you test from? The first test is obviously from a client within internal subnet, but who is the client on the second test? On the “outside”, or still in the internal subnet?

In the latter case, what is the route to the external IP?

As others have noted, your “external IP” is probably not on the server. (If it were on the server, then you would not need Google to find it – just nmcli in the server.)

Lets have client X at 10.10.1.x.
The server Z has only one address:
Router Y has address 10.10.1.y and external IP a.b.c.d.

Case 1: X connects to Both are on same subnet and traffic is “link local”. Fine.

Case 2:
X connects to a.b.c.d. That is not link local. Therefore, X sends the packets to “gateway” 10.10.1.y in hope that Y knows where a.b.c.d is.

  • If Y has no “port forwarding”, then X attempts to ssh into Y
  • If Y does have port forwarding rule “forward to a.b.c.d:2021 into”,
    then a packet “from=10.10.1.x to=” travels to Z. The Z will send reply directly to 10.10.1.x.
    The X does not expect replies from because it tries to talk to a.b.c.d
  • If Y has additional (and suitable) sNAT rule to masquerade sender, then it will forward the packet as “from=10.10.1.y to=”. The Z will reply to Y, and Y will reverse the sNAT and dNAT so that it sends a reply “from=a.b.c.d to=10.10.1.x” back to X

Lets have client W outside, at e.f.g.h. It sends packet “from=e.f.g.h to=a.b.c.d”.
The router Y has only the port forward rule, so it forwards a packet “from=e.f.g.h to=”.
The Z replies with “from= to=e.f.g.h”, which it sends to gateway 10.10.1.y.
The router forwards the reply – with dNAT undone – “from=a.b.c.d to=e.f.g.h” and W is happy.

1 Like

Thanks, managed to fix this.

The issue was basically due to a reinstall of the Linux server and router setup/configuration/scanning which managed the public IP.

1 Like