Basic SSH server hardening

When discussing some of my recent findings with Kippo I’ve been asked a few times for suggestions for how people can prevent their systems from being compromised via this vector. A quick Google search shows that there are already a number of good resources covering the options, including: Debian Administration Article and Securing Debian Manual. However, the high number of options can leave people unsure where to start so I’ll summarise some of those that are more common and can provide the highest return on investment for the time taken to make the change.
N.B. a lot of the suggestions below are valid for most/all remote access functionality.
Restrict access from unknown locations
If possible (it isn’t always) restrict access to only come from known and trusted sources. This can be down at multiple choke points in the network and system; perimeter firewall, host firewall (iptables etc.) or sshd config. For working with sshd the /etc/hosts.allow and /etc/hosts.deny, for example:

#Corporate HQ gateway


#Generic Deny All
sshd: ALL

It doesn’t matter how insecure your system is, if an attacker can’t connect and communicate with a vulnerable service they can’t exploit it, period.
Restrict remote root access
Preventing remote access to the root account can reduce the damage that can be caused by a compromised. With SSH this can be achieved with a single configuration line:

PermitRootLogin no

Only allow access to specific accounts
Does every account on you system need to be able to remotely access the system via SSH? No? Then why can it?
Remote system access can be restricted on a per user basis. This can be either as a whitelist using the AllowUsers directive or as a blacklist with the DenyUsers directive. For example, if I only wanted to allow my own account access via ssh:

AllowUsers andrew

These capabilities can be useful with certain honeypot systems; if you create a weak user account linked with an ftp or pop3 honeypot (for example), then the same weak accounts can be prevented from gaining access to a shell with the DenyUsers directive, limiting the weak account to only access those services that are being monitored.
Run on non-standard port
Yes, this is ‘security by obscurity’; if this is the only change you make you haven’t really improved security any, but it is still useful as part of wider security posture. Attackers are continually scanning the internet looking for new systems to exploit, currently the ISC statistics show connections to tcp22 at around 100k targets; even moving to a relatively common alternative port of 2222 drops the malicious traffic by around 90%.

Port 2222

This reduces the number of malcious attempts targeting the service, which will both reduce processor/network load and ‘noise’ in the log. If you now get a burst of failed log-in attempts in the logs, then this may be indicative of a specific attacker rather than just the usual background noise of bots and worms scanning for new victims.
Implementing the above can drastically improve SSH security above the defaults, with a relatively small effort required providing a great ROI. So what’s your excuse? Go harden that SSH installation
–Andrew Waite

Join the conversation


  1. Consider also disallowing Password authentication and using only key-based authentication in ssh (especially if you are unable to lock things down by IP, for instance if your ssh users are restricted to dynamic source IPs)
    On most modern distributions, key-based auth is already enabled by default, so you may only need to set in /etc/ssh/sshd_config

    PasswordAuthentication no

    Also, a recent spate of ssh attacks have taken advantage of keyboard-interactive authentication. Again, most modern Linux distros set this by default, but ensure this is on your config

    ChallengeResponseAuthentication no

    1. WOW! That was quick off the mark 😉
      Yeah, totally agree that key based authentication is the way forward. But I wouldn’t include it under ‘basic’ as it requires a shift in how a user accesses the system from the standard and understand username and password. Not a problem on a single user system, but if a large number of users need shell access then blindly implementing key only authentication is a sure fire way to cause your helpdesk to explode.
      To paraphrase Tom, ‘I don’t want a bunch of emails saying “I got in trouble because I did what InfoSanity said…”)’

  2. True that – I realised afterwards it may not be considered ‘basic’ – on the other hand, even before making any firewall changes, setting up an ssh keypair and switching to key-based only, could often be enough (arguably harder to spoof a private key than an IP!) and from experience, the afternoon of pain sending a tutorial around to your users and getting them to email you back their public keys, is well worth the effort when securing server you can’t totally firewall off 🙂
    Sorry for the trigger-happy spam comment 🙂

  3. I love vectors like these when pen-testing networks. I think root access to SSH, standard port and allow any IP to connect are wonderful for me! Bad for the Network Admins.
    Very good report Andrew. I think these are some great starting points, even if its not a fully secure SSH server, changes like these cut down the amount of people that can pull off an attack.

  4. These are very good tips. If only admins need to login, to get around the issue of having an IP lockdown and then your ISP changes your IP, you could either lockdown the IP to your ISPs local network or better yet have a very cheap VM on standby with a static IP and with access for that IP to your server. This way if your IP all of a sudden changes and you’re locked out all you need to do is daisy chain via your cheap VM’s IP, login and then update your dynamic IP.

  5. That’s a good point, always make suer you’ve got multiple points into your server in case something changes. In my standard setup I’ll allow multiple source locations (home/work/etc.). Don’t forget you can (usually) fall back on physical console access as a last resort.

Leave a comment

Your email address will not be published. Required fields are marked *