Why Do I Change the Default SSH Port

It’s not a security through obscurity, as there is nothing obscure whatsoever. Security is always about layers.
[UPDATE 2015]: I no longer change the default SSH port – I adopted a habit to put services behind a VPN.

The Point of Doing This

1. Most script kiddies don’t go after secured systems nowadays, they just use botnets to brute-force unsecured servers to gain easy access.

2. Full range port scan is a time consuming thing (try yourself!) – botnets don’t normally do that.

3. If we change the default SSH port, it will likely never be discovered by a botnet – don’t be a low hanging fruit!

4. We keep auth logs clear from failed password login attempts for “alice” etc.

5. Our network the servers are hosted on has no out traffic restrictions.

6. All applications we use to get access to SSH server (Putty, WinSCP, SCP etc) can easily change the port.

We’d rather use firewall rules to restrict access to specific public IPs, but quite a few users get dynamic IPs from their ISPs.

We could use VPN, but this isn’t always a solution.

Don’t Get the Wrong Impression

1. This is not to protect servers from blackhats.

2. If somebody is particularly after us, they will obliviously do a full-range nmap scan and find out all ports that are opened. In minutes. Or less.

3. Yes, we could implement an IDS system (i.e. Snort) which can block IPs if several ports are scanned in a row, but again, blackhats can use a botnet with thousands of different IPs and all ports will still be scanned in minutes.

4. Again, this is not to protect servers from blackhats.

My SSH Policy

  1. Always deny root access.
  2. Change SSH port to any unused well-known (privileged) TCP port (f.e. TCP 12, unassigned by IANA) and keep is as a general rule, but not as a secret.
  3. Use AllowUsers (and DenyUsers) to whitelist users who need SSH access.
  4. Disable password authentication where possible and use auth keys instead.
  5. Install and configure denyhosts if using password authentication.

Changing default SSH port is not a security through obscurity, as there is nothing obscure whatsoever, if users know the policy.

Real Life Example

These are one day’s logwatch entries on two server before changing the default SSH port. No such thing appears on a non-default port.

--------------------- pam_unix Begin ------------------------

sshd:
 Authentication Failures:
 root (<IP_REMOVED>): 55542 Time(s)

---------------------- pam_unix End -------------------------

--------------------- SSHD Begin ------------------------

Error in PAM authentication:
 Authentication failure for root from <IP_REMOVED> : 55542 Time(s)

 **Unmatched Entries**
 reverse mapping checking getaddrinfo for <IP_REMOVED> failed - POSSIBLE BREAK-IN ATTEMPT! : 108 time(s) 
 reverse mapping checking getaddrinfo for <IP_REMOVED> failed - POSSIBLE BREAK-IN ATTEMPT! : 2 time(s)

---------------------- SSHD End -------------------------
 --------------------- pam_unix Begin ------------------------

sshd:
 Authentication Failures:
 unknown (<IP_REMOVED>): 15210 Time(s)
 root (<IP_REMOVED>): 798 Time(s)
 adm (<IP_REMOVED>): 12 Time(s)
 lp (<IP_REMOVED>): 12 Time(s)
 sync (<IP_REMOVED>): 10 Time(s)
 bin (<IP_REMOVED>): 8 Time(s)
 mail (<IP_REMOVED>): 8 Time(s)
 uucp (<IP_REMOVED>): 8 Time(s)
 ftp (<IP_REMOVED>): 6 Time(s)
 news (<IP_REMOVED>): 6 Time(s)
 operator (<IP_REMOVED>): 6 Time(s)
 sshd (<IP_REMOVED>): 6 Time(s)
 daemon (<IP_REMOVED>): 4 Time(s)
 nobody (<IP_REMOVED>): 4 Time(s)
 postmaster (<IP_REMOVED>): 4 Time(s)
 halt (<IP_REMOVED>): 2 Time(s)
 shutdown (<IP_REMOVED>): 2 Time(s)
 Invalid Users:
 Unknown Account: 15210 Time(s)
---------------------- pam_unix End -------------------------

--------------------- SSHD Begin ------------------------

Illegal users from:
 <IP_REMOVED>: 15216 times

 Login attempted when shell does not exist:
 cron : 2 Time(s)
 sshd : 6 Time(s)

 Error in PAM authentication:
 Authentication failure for adm from <IP_REMOVED> : 12 Time(s)
 Authentication failure for bin from <IP_REMOVED> : 8 Time(s)
 Authentication failure for daemon from <IP_REMOVED> : 4 Time(s)
 Authentication failure for ftp from <IP_REMOVED> : 6 Time(s)
 Authentication failure for halt from <IP_REMOVED> : 2 Time(s)
 Authentication failure for illegal user 123456 from <IP_REMOVED> : 2 Time(s)
 Authentication failure for illegal user Bobby from <IP_REMOVED> : 4 Time(s)
 Authentication failure for illegal user PlcmSpIp from <IP_REMOVED> : 4 Time(s)
 Authentication failure for illegal user Programas_Linux from <IP_REMOVED> : 2 Time(s)
 Authentication failure for illegal user Victor from <IP_REMOVED> : 2 Time(s)
 Authentication failure for illegal user aalmache from <IP_REMOVED> : 2 Time(s)
 Authentication failure for illegal user aalmeida from <IP_REMOVED> : 2 Time(s)
 Authentication failure for illegal user aaranda from <IP_REMOVED> : 2 Time(s)
 Authentication failure for illegal user aaron from <IP_REMOVED> : 10 Time(s)
 [...]
 ... many many lines ...
 [...]
 Authentication failure for nobody from <IP_REMOVED> : 4 Time(s)
 Authentication failure for operator from <IP_REMOVED> : 6 Time(s)
 Authentication failure for postmaster from <IP_REMOVED> : 4 Time(s)
 Authentication failure for root from <IP_REMOVED> : 798 Time(s)
 Authentication failure for shutdown from <IP_REMOVED> : 2 Time(s)
 Authentication failure for smmsp from <IP_REMOVED> : 12 Time(s)
 Authentication failure for sync from <IP_REMOVED> : 10 Time(s)
 Authentication failure for uucp from <IP_REMOVED> : 8 Time(s)
 Error in service module for illegal user from <IP_REMOVED> : 26 Time(s)

 **Unmatched Entries**
 Address <IP_REMOVED> maps to <DNS_REMOVED> , but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! : 604 time(s)
 Address <IP_REMOVED> maps to <DNS_REMOVED>, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! : 4 time(s)

----------------------- SSHD End -------------------------