Simple Server Security
Setting up SSH, UFW, and Fail2Ban to make your (home?) server secure
Every time I set up a new server (either homeserver or VPS) I run through the same basic security setup. This post should serve as a handy reference for those not wanting to think too hard about making their server protected to a reasonable degree, and an overview of why each of these components is helpful.
I’ll cover:
- Key-only SSH authentication
- Firewall setup with UFW
- enabling fail2ban
SSH #
SSH is the natural and really only way to access your server remotely.
When buying a VPS my experience has been that I will simply get an email with a plaintext but relatively secure password akin to those made by a password manager.
This may trick you in to thinking that this is a secure way to access the server - after all, the password is more complex than password1234 - but password based authentication is always vulnerable.
It is far more secure to completely disable the ability to log in with passwords, right after setting up SSH.
I already have my SSH keys set up on the machines I use to access my servers.
They are easily generated on linux via ssh-keygen -t ed25519.
Once there are keys on the local machine, it is simple to copy them over to the server via ssh-copy-id root@YOUR_SERVER_ADDRESS.
Naturally this will still be done using password authentication - this shouldn’t be disabled yet.
There should be some sort of confirmation that this ID has been copied to the server.
At this point, open a separate terminal window and try to run ssh root@YOUR_SERVER_ADDRESS.
If the keys copied over correctly, no password should be required to log in.
Users #
It is best practice to set up a user other than the root user to log in to on a public-facing VPS. This is another layer in the swiss cheese model of (cyber)security to keep attackers out. All that is necessary to do this is the following:
adduser loginuser
usermod -aG sudo loginuser
groups loginuserThe groups command should show the loginuser (or whatever username you desire) is a member of the sudoers group.
Once this is done, root login can be disabled.
SSH Configuration #
The SSH configuration file can now be adjusted to disallow any password based authentication, and only allow SSH keys to be used.
Running sudo nano /etc/ssh/sshd_config (or replace this with your editor of choice, if installed) will allow the following settings to be changed in the configuration file:
PermitRootLogin no
AllowUsers loginuser
PubkeyAuthentication yes
PasswordAuthentication noRestart the ssh daemon with sudo systemctl restart sshd and these settings will be applied.
At this point, running ssh loginuser@YOUR_SERVER_ADDRESS should get you on the machine and ssh root@YOUR_SERVER_ADDRESS should not be allowed.
This is realistically the first stopping point for setting up a server.
At this point it is relatively secure with:
- SSH-only authentication
- Password auth disabled by default
- Root access disabled by default
Uncomplicated Firewall (UFW) #
UFW will already be installed in almost all Ubuntu servers. As a firewall, its main use case is in default-denying incoming requests unless the ports are expressly opened up to the wider internet. This is very beneficial psychologically - it requires you to think about what you need to enable, rather than listing things that must be disabled. Commands fit the theme of the name ‘Uncomplicated Firewall’ very well. There are very few commands necessary to completely deny all incoming connections that are not related to the ports you want to use:
sudo ufw allow ssh
sudo ufw allow 443/tcp
sudo ufw default deny incoming
sudo ufw default allow outgoingWith these settings, the VPS will allow connections only on the standard SSH port of 22 and the standard HTTPS port of 443.
Naturally unsecured HTTP could be allowed by adding ufw allow 80/tcp, but it is trivial enough to set up secure access with HTTPS that there should be no need to do this.
To enable and check what UFW is configured with, run the following (after triple or quadruple checking ssh is allowed):
sudo ufw enable
sudo ufw status verboseThe last command should show reiterate the enabled settings:
- 22/tcp is enabled (for SSH)
- 443/tcp is enabled (for web traffic)
Nothing else should be enabled at all. This reduces the possible attack surface for your server, especially helpful if you are trying to test any web tools but do not want them exposed to the world wide web.
Fail2Ban #
Fail2Ban is yet another helper to very easily ban repeat attackers who fail to authenticate a number of times. Although disabling password authentication and setting up UFW will substantially reduce the attack surface of a VPS, setting up Fail2Ban is an easy way to reduce spammy attacks. This is the only thing I am suggesting not automatically installed, at least on most Ubuntu server distributions I know of. It is trivial to install:
sudo apt update
sudo apt install -y fail2banFail2Ban has some automatic defaults that are generally sensible.
However, I adjust the configuration to be a little more aggressive than normal.
It is important to create your own local copy cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
I set the following:
bantime = 24h
maxretry = 3
[sshd]
enabled = trueThere is not much else to set with Fail2Ban - it will work just fine with these settings.
That’s It #
This is everything you should need to do to set up a secure server, VPS or otherwise. Following the swiss cheese model of having multiple different tools blocking the way in for attackers may seem mildly paranoid, but this is always a good option when security is concerned. Going through the entire process I’ve outlined doesn’t take very long either, only a few minutes at most for the server this site is hosted on.