Ubuntu 20.04 VPS Cheatsheet

A no-frills checklist for configuring and securing an Ubuntu 20.04 VPS.

Create a User Account

A newly initialized VPS has a single root user account. This account is too powerful for general use so our first task is to create a regular user account for ourselves.

First, log in to the root account using the server's IP address:

ssh root@xxx.xxx.xxx.xxx

If this is our first time logging in we may be prompted to change the root password.

Next, add a new user to the system:

adduser <username>

We need to enter a password for the new user. (We also get asked some optional questions which we can ignore by hitting ENTER.)

We can now grant administrative privileges to our new user account by adding it to the sudo group.

usermod -aG sudo <username>

This will allow us to temporarily grant ourselves root access to the system using the sudo command whenever necessary.

Enable Public Key Authentication

We want to enable public key authentication for our user account. We do this by generating a public/private key pair on our local machine using ssh-keygen, then installing a copy of the public key on the server.

We have two options for copying our public key to the server. We can use the ssh-copy-id script if it's installed on our local machine:

ssh-copy-id <username>@xxx.xxx.xxx.xxx

Or we can copy it manually. First print and copy the public key:

cat ~/.ssh/id_rsa.pub

On the server, switch to the new user account and create a .ssh directory in the user's home directory:

su - <username>
mkdir .ssh
chmod 700 .ssh

Create a file called authorized_keys, paste in the public key, and restrict its file permissions.

vim .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
exit

The exit command returns us to the root user account.

Configure SSH

We can harden our server by disallowing SSH access to the root account and by disabling password authentication altogether.

Open the SSH configuration file:

vim /etc/ssh/sshd_config

Update the following settings:

PermitRootLogin no
PasswordAuthentication no

Optionally, set SSH to use a random port and turn off X11 forwarding to speed up terminal access:

Port <something other than 22>
X11Forwarding no

Now restart the SSH daemon so the changes can take affect:

service ssh restart

Important: test the new configuration by logging in to the server using the new account before logging out as root:

ssh <username>@xxx.xxx.xxx.xxx

Update System Packages

Update the system's installed packages:

apt update        # update the list of available packages
apt full-upgrade  # install newest versions of all packages

Install the English language pack:

apt install language-pack-en

Set the server's timezone:

dpkg-reconfigure tzdata

Install the ntp service to keep the system's time synchronized with the rest of the world:

apt install ntp
service ntp start

This service will automatically restart after each boot.

Enable Firewall

UFW is a simple frontend for the iptables firewall:

apt install ufw

Set up the firewall to enable SSH access:

ufw allow ssh         # allow ssh on the default port (22)
ufw allow 2222/tcp    # allow ssh access on a custom port

We may also want to enable access to web and mail servers:

ufw allow 25/tcp      # allow SMTP access
ufw allow 80/tcp      # allow http access
ufw allow 443/tcp     # allow https access

We can review these rules with the ufw show added command. To enable the firewall run:

ufw enable            # turn on the firewall
ufw status verbose    # print a status report

Once enabled, the firewall will automatically restart after each boot.

Install Fail2Ban

Fail2Ban protects the system from brute force attacks by monitoring login attempts and automatically locking-out suspicious IP addresses.

Install fail2ban:

apt install fail2ban

The service can be managed with the following commands:

service fail2ban start
service fail2ban stop
service fail2ban restart

Copy the service's configuration file before adding any customizations:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Changes should be made to the jail.local version.