Changing the default SSH port is most definitely security by obscurity, and most definitely shouldn’t be the only security measure put in place to protect against unauthorized remote system access over SSH. However, it is still damned effective against brute-force attacks and probes. Free up some system resources by changing the default port number; I’ll show you how it’s done in Fedora Linux.
The practice of changing the default SSH port is equivalent to walling up your main entrance only to construct another identical entrance around the corner. Most foot traffic will walk up to the old entrance by the busy street and walk away when they don’t find the door. It doesn’t take much looking to find that there is another entrance just not where one expects to find one, which of course requires more time and effort. The busy street is full of more easily accessible entrances to other buildings anyway so why even bother making an effort. It doesn’t really improve security, but it does reduce the number of people who are constantly knocking at the door while shouting out nonsense phrases trying to gain entry.
Simply by changing away from the default port, I reduced stupid scripted attacks by 100 %. I could almost hear the SSH daemon sigh of relief when it finally got some peace and quiet. Slightly more elaborate scripts that spent the time to discover the new port were also clever enough to only attempt to login once, discover that my server doesn’t allow password based login, and then they went away as well. This effectively eliminated automated repeated attempts at gaining access. For more determined attackers, you need to be more proactive in blocking then. E.g. you can setup SSHGuard to add block rules to FirewallD when attackers are detected.
To change the default port under Fedora, and in any other Linux distribution for that matter, requires a change to the default Port 22 option in /etc/ssh/sshd_config to the port number you want to use. We’ll use port 722 in all the examples going forward. Either edit the configuration file manually, or blindly trust this search-and-replace script to do it for you:
Fedora Linux has Security Enhanced Linux (SELinux) and a firewall (FirewallD) enabled by default. The next few steps only apply to these systems on Fedora.
SELinux will by default expect incoming SSH connections to go over port 22, and we’ll need to adopt this policy to let through traffic on the new port instead. The semanage program can be used to modify the policy and verify the result afterwards. The first command below will add the new port number to the “ssh_port_t” policy, and the second command will print the same policy afterwards so we can verify that the new port number was added.
Then the local FirewallD is assumed to have been setup to allow the ssh service. The service definition for ssh needs to be updated to allow traffic through on the new port:
The configuration changes are now in place and you can reload the services to make them take effect:
You should disconnect and reconnect to the server on the new port (ssh -p 722 email@example.com). You may be disconnected after running the previous command. After verifying that the new port is accessible, we remove the default SSH port 22 from the firewall configuration to reject future connections to the old port:
The commands used in this article were all derived from examples scattered around on the Fedora Documentation website.
If you’re using Fail2Ban, be sure to update the port number in the configuration there too.
Another common way to achieve a similar effect is to configure a NAT rule on your router or gateway device that redirects port 722 on your external IP address to port 22 on the internal IP of your server. However, that has some hidden pitfalls: Primarily, it does nothing for IPv6 as NATs and pre-routing isn’t really a thing. It also does nothing for attacks originating from inside your network in situations where Jeff from accounting sets up his own Wi-Fi access point with no password to improve signal strength around his desk. By then, you have other problems too but it’s still better to configure this on the service device so it’s configuration will match the publicly exposed configuration.