Why putting SSH on another port than 22 is bad idea

March 12, 2012

I see a lot of companies and users moving their SSH port to a non-privileged port like 2222 or even 36797. Now, there are few reasons why people would do this, all of them incorrect and dangerous. Some of those reasons I will not even mention, just to protect the people who actually use them :) But what it comes down to, is that people like to move this port away in order to lower the number of attacks on the SSH port.

Now, at first glance, this seems a valid reason: if you don’t know which port to attack, you can’t attack it at all :-). But if you re-read that last line, you will notice this is nothing more than security through obscurity, and if you think that that is a good idea, you should not be allowed behind a computer.. ever…

But there are more reasons why this is a bad idea and one of the most important reason has to do with a bit of the (Linux) way of handling TCP/IP ports. When you are logged onto a system as a non-root user (anyone not being uid 0), you cannot create a listing TCP or UDP port below 1024. This is because port numbers below 1024 are so-called privileged ports and can only be opened by root or processes that are running as root. So for instance, when your webserver (apache, nginx etc) will start, it will do so as the privileged root user in order to open up a listening connection to port 80 (the port that by default will be used for HTTP traffic). Now, as soon as the port is opened and everything that needs to be done as root is done, the webserver will fall back to a non-privileged user (either the www-data, apache, or nobody user). From that point, when something bad is happening, it is only limited to the rights that that user has.

Now, back to SSH: when we start SSH on port 22, we know for a fact that this is done by root or a root-process since no other user could possibly open that port. But what happens when we move SSH to port 2222? This port can be opened without a privileged account, which means I can write a simple script that listens to port 2222 and mimics SSH in order to capture your passwords. And this can easily be done with simple tools commonly available on every linux system/server. So running SSH on a non-privileged port makes it potentially LESS secure, not MORE. You have no way of knowing if you are talking to the real SSH server or not. This reason, and this reason alone makes it that you should NEVER EVER use a non-privileged port for running your SSH server.

On to the next reason not to change ports: A lot of applications actually EXPECT ssh traffic on port 22. Now this might be a debate wether or not those programs are developed properly, but it’s a fact. Even though you can easily change the port in many applications but not all of them do. Trust me, it WILL be annoying for developers, sysadmins and users to operate on your SSH-port 52241, especially since they are using 20 boxes, each with a different SSH port.

Another issue: many corporations have incoming and outgoing firewalls, meaning you cannot goto any site to any random port and expect it to work. Some secure ports, like port 22 are often exempt from that, while other ports like port 25 or 110 are blocked.

Now, let’s pretend you STILL want to move the port away because you get so many attacks on your SSH port. First of all: are you able to logon as root? If so, fix that now. Secondly: are you using passwords? If so, fix that now and change into public key authentication. But think about it: is it a problem to have so many people banging at the front of your house? They are just there testing your defenses! :-) I’d rather have an angry mob outside my house knowing it would mean I would do everything to make sure they can’t break into my house, than to have an open door, that I do not know about, until some lonely passant just drops in to say hi (and trash the place, or worse).

But if you are REALLY worried about that angry mob, there are better ways to hide the door than to move it. Try port-knocking. Again, security through obscurity, but if you must, this is probably the only viable way to do it. There are several ways to implement port-knocking. There are 3rd party tools, which are A) way to big and complex and B) are implemented in userland so don’t use them. Instead, Iptables has got a very nifty module called “recent”, which allows you to create simple – yet effective – port knocking sequences.

Take a look at the following example:

What this does, is that as soon as something tries to connect to port 3456 (yes, a non-privileged port, but no problem, nothing is running on it), it will set a flag called “portknock”. Now, when we try to setup a connection to the SSH port, it will check to see if your IP has set a “portknock” flag during the last 60 seconds. If not, it will not accept the connection. And the third line will by default deny any access to SSH together as a failsafe. (I’ve heard before that it would be hard for users to remember that they need to connect to another port first, but somebody who cannot click a link, type a url, or telnet to a port, should he or she really have SSH access to begin with???).

Now, don’t directly copy/paste this into your firewall, but you can see how easy it is to “hide” your ports. You can even create a whole serie of knock sequences if you like but this will only annoy your users and gains you nothing.

Again, this does not change ANYTHING on the fact that it should not matter if your port is out in the open or not. Don’t fall for security through obscurity, because that will probably be the easiest way to get your box hacked. And please, as a hosting company, a system administrator or even a developer, don’t ever tell others that moving your SSH port away is a good thing. Because it’s not, and it never will be.



11 Responses to Why putting SSH on another port than 22 is bad idea

  1. March 12, 2012 at 16:31

    To your many excellent reasons, I would add one more: the -P option to scp is a pain in the butt to remember (why is it capitalized? Why must it come first?) and, a related issue, lots of scripts you may have handy don’t have a provision for a port number. It is super annoying and adds no security. I hope web hosts will drop this silly policy.

  2. joe
    March 13, 2012 at 01:04

    This whole article hangs on the assumption that you’re using passwords for SSH. That is the bigger issue. It doesn’t matter what port you run SSH on. If someone has control of your box and can setup an SSH daemon, you’re screwed. Also, if a user starts SSH on a different port, the keys will mismatch since the user can’t access the private key. So the person connecting will get a VERY nasty message that the system is not the system the intend to connect to.

    • Joshua Thijssen
      March 13, 2012 at 09:12

      I totally agree that using keys is more secure than using standard passwords, but to be honest most users who are moving their SSH port away from 22 ARE using password authentication and not ssh keys (if they did, they probably wouldn’t even think of moving the port probably). Also I stated in the post that using passwords wasn’t the best thing to do either :)

      Connecting to a non-privileged port should raise a red-flag nevertheless. Unless your box has been rooted, you are certain that your are connecting to a “real” SSH daemon on port 22, however, when you are connecting to port 2222, EVERY user on that system can pretend they are an SSH server (they even CAN be a ssh server, with a key-logger compiled in for example). It would be easy enough to create a simple application that would scan for a listing port, and start your own non-privileged server as soon as the port is free. Most users would probably type in their passwords anyway if SSH asked for it..

  3. John Isaac
    April 8, 2012 at 01:11

    Lost me at “Some of those reasons I will not even mention, just to protect the people who actually use them” huh? seriously? stop trying to sound so mysterious.

  4. JC Arnu
    April 19, 2012 at 22:47

    Another point may be to use sslh (yes SSLH) on 443 port. SSLH is a protocol diverter tool to divert either SSH or SSL (HTTPS) protocol to local running servers (other ports). This is quite handy when your proxies or company firewall only allow 80/443 outgoing ports. This does not restrict your excellent post, but it may be helpful for some people reading this.

    So kudos to Yves Rütschlé who wrote this nifty tool :)

    • Joshua Thijssen
      April 19, 2012 at 23:08

      Cool tool. Thanks for the tip.

  5. ZaraK
    June 6, 2012 at 21:16

    For all CentOs fans , knokd RPM-package contains a port-knock deamon/client .
    Configuring and installing the package is simple , read this article for more information : http://bit.ly/KxJWRj .

  6. Andre
    November 20, 2012 at 15:13

    What I have done is leave all the ports on the computer as default (with good firewall and security on them), but set my router so that a more obscure port on the Internet side routes to the common port on the Computer side. So the Internet sees port 55555 open for SSH, but my computer still just uses 22. This may or may not be a feature available on most routers – I’ve never looked into it.

    This way (I think), I avoid the problems you suggest, have a fully accessible (to me) system, but also manage to avoid the bots constantly filling my logs. Since doing this, there has been no bot activity.

  7. p0wer
    December 9, 2012 at 16:13

    What about different, but still privileged ports? Like 876 for example. Firewall problem exists, but userspace server can’t be bound this way. In the end, changing a port to a different value should not have a huge impact if this is a server supported by a small amount of well-known people (one admin, few webmasters)

  8. Kenan A.
    February 27, 2013 at 20:33

    Keys against passwords ?
    We have seen so MANY of those secure keys mistakenly shared on GIT,and realised again nothing is MORE secure.

  9. Dicer
    February 28, 2013 at 01:48

    Security through obscurity is very valuable! Don’t discredit it so easily! It is only a fail if it is your ONLY security!
    Security is always about layers! Adding an obscurity layer is not bad, as long as it doesn’t hurt other layers (like the mentioned unprivileged high ports).

    My argument FOR moving the ssh port to another one between 1 and 1024: Imagine a new 0day remote exploit for openssh is released. Now guess how long it will take until your sshd on port 22 is owned? Of course you are not immune against attacks on port 666 either, but it might give you that extra time to install (or wait for) a patch!