Simple Server Hardening


As I mentioned, just about every server you will encounter turns on SSH by default, and there is an assumption that you will use it for remote administration. Here are a few simple changes you can make to your /etc/ssh/sshd_config file that take only a second but make it more secure.

First, disable root logins and make sure that you use only SSH protocol 2 (previous protocols have known vulnerabilities). In many distributions (in particular many cloud images), these steps already may be done for you:

PermitRootLogin no
Protocol 2

A lot of people focus way too much, in my opinion, on SSH brute-force attacks when they talk about server hardening. It's true that if you put a Linux server on the internet, one of the first things you will see in your logs is a steady stream of SSH brute-force attempts. Many sysadmins go to lengths that I think fall somewhere between ineffective, absurd and overkill, including moving SSH to some random port (security by obscurity) or using a system like fail2ban. With fail2ban, your system reads failed login attempts and creates firewall rules to block attackers after a few failed attempts. This seems sensible on the surface, but it has a few problems:

  1. This stops only attackers who have one machine—most have botnets and spread brute-force attacks across many IPs.

  2. If you have a weak, easily guessable password and a common user name, they might guess the password before fail2ban kicks in.

  3. It's risky to let attackers perform an action that automatically updates your system's firewall rules.

  4. Usually internal networks are whitelisted—attackers still can brute-force attack you from a different compromised machine on your network.

Instead of going through all of those steps to mitigate SSH brute-force attacks, I recommend that you eliminate the attack entirely: disable password authentication and rely on SSH keys only. Before you enable this option, be sure that everyone who logs in to this machine (or at least the administrators) have generated and tested logging in using SSH keys—you wouldn't want to get locked out. When you are ready, change the PasswordAuthentication parameter in your sshd_config to:

PasswordAuthentication no

The final quick SSH hardening step is to restrict which cryptography cipher suites and algorithms to use, so that you use only the ones that are considered to be safe by today's standards. I'm no cryptographer, but I don't have to be one to look at the recommendations from cryptographers and copy and paste them into my SSH config:




Once all of these settings are in place, restart the SSH service to use them.

Account Hardening

For general hardening of the system accounts, the best recommendation I can make is to disable the root account altogether and use only sudo. You also should avoid direct login to any shared accounts, whether it's the root account or some role account like a user that manages your application or web server. By requiring users to log in as themselves and then sudo up to root or role accounts, you provide a nice audit trail for who did what, and you make revoking access simpler when users no longer need an account—since the shared accounts won't have a password, you don't have to change them every time a member of the team leaves; instead, you can just remove that user's account.

Most distributions currently include sudo, and some also either disable the root account by default or allow you to disable it during installation. Otherwise, you simply can edit your /etc/shadow file and replace whatever password you have in place for the root user with a * symbol. Just make sure you do have sudo working first with at least one account so you don't lock yourself out.

When using sudo there are a few practices you should follow to help keep it secure. First, while the use of NOPASSWD sudo rules (rules that don't require you to enter a password) are somewhat unavoidable for dæmons that may run cron jobs like backup jobs, you should restrict any NOPASSWD sudo rules to just those dæmon role accounts and require all real users to type in a password. As much as possible, you also should follow the principle of least privilege and grant users sudo access only to the specific commands they need instead of granting them access to run all commands as a particular user (especially the root user). Finally, if you find yourself granting users access to a general-purpose command to do something specific (like granting them access to service or systemctl so they can restart just one service), consider creating a simple shell script that runs the command with only the specific parameters you want and granting them sudo access to that script instead.

Although these hardening steps aren't the only things you should do to lock down your server, they are a good start and should take only a few minutes. In my next article, I'll add another round of simple hardening tips, including SSH client hardening and cloud hardening steps, and I'll finish up with some general-purpose recommendations.


Kyle Rankin is SVP of Security and Infrastructure at Zero, the author of many books including Linux Hardening in Hostile Networks, DevOps Troubleshooting and The Official Ubuntu Server Book, and a columnist for Linux Journal. Follow him @kylerankin