Secure Ubuntu 20.04

Secure Ubuntu 20.04

Initial Set-up

Assumes you have a fresh install of a nice new Ubuntu 20.04 server sitting in the cloud with root ssh access.

If you are looking for a cheap hosting solution for your tile server take a look at the Contabo VPS XL SSD at the time of writing it cost just €26.99/month for 60Gb Ram, 10 core CPU and 1.6 Tb SSD with unlimited traffic!

Connect to your Server

Open a terminal and connect via ssh as root user;

    ssh root@aaa.bbb.ccc.ddd

Replace aaa.bbb.ccc.ddd with your server’s ip address.

Upgrade Software

Always a good idea to get the latest patches and security fixes:

apt update; sudo apt upgrade

Avoid Root login

Rather than using a clunky placeholder (like <username>) I’m just going to use chris. Replace it with the username of your choice.

Create a user

It not a good idea to use the root account and later on we’ll disable root login so we need to create a user account:

adduser chris

Enter a strong password when prompted. Personally I use a Padloc to generate strong, random passwords.

Fill in the user information when prompted.

Add user to the sudo group

Members of the ‘sudo’ group have sudo access by default on Ubuntu. Use the usermod command to add the user to the group:

usermod -aG sudo chris
Test the sudo access

Change to your newly minted user:

su - username

Use sudo to run the whoami command:

sudo whoami

If the user has sudo privilege then the output of the whoami command will be root

Note: you’ll need to enter the password the first you use sudo in a session.

You can now login using your new account and use sudo when you need elevated permissions. So now would be a good time to log out


You need to exit twice, once to exit back to the root account then to exit the ssh connection. Now re-connect using your new user account.

ssh chris@aaa.bbb.ccc.ddd

Locking down the server

By this point you should be logged in using your ‘non-root’ user account. If not, why not?

As you can now login and perform admin tasks using your ‘non-root’ id we’ll remove the PermitRootLogin option:

sudo nano /etc/ssh/sshd_config


PermitRootLogin no

Now restart the SSH server:

   sudo service ssh restart

Next up we will harden out server a little,

Setup a basic firewall

Setting up a tile server can take quite a while, so initially we’ll set-up a firewall to restrict in-bound connections to ssh only. Let’s check the current status:

sudo ufw status

Chances are this will report Status: inactive

It’s a good policy to close all ports on the server and only open those that are actually required. First we’ll block all incoming connections and allow all outgoing connections from the Ubuntu 20.04 LTS box:

sudo ufw default allow outgoing
sudo ufw default deny incoming

We need to allow connections on the ssh port or we won’t be able to log back in again.

sudo ufw allow ssh

If you are using a non-standard port for your SSH daemon then you simply specify the port name instead of the service name:

sudo ufw allow 2222

We can now enable the firewall:

sudo ufw enable

You will receive a warning, but we just set up the rule to allow SSH connections, so it is fine to continue. Type y and hit ENTER.

You can see that SSH connections are still allowed by typing:

sudo ufw status


Status: active

To                        Action      From
--                        ------      ----
22/tcp                    ALLOW       Anywhere
22/tcp (v6)               ALLOW       Anywhere (v6)

The firewall is now blocking all connections except for SSH, we will adjust the firewall settings again later once we are ready to start serving tiles.

Set up Two Factor Authentication (2FA)

Using two factor authentication helps prevent brute force attacks;

  1. install google’s libpam authenticator module

     sudo apt-get install libpam-google-authenticator
  2. Modify pam ssh configuration to use google authenticator:

     sudo nano /etc/pam.d/sshd

    Add line at the top:

     auth required
  3. Modify sshd config to use challenge response authentication

     sudo nano /etc/ssh/sshd_config

    Change ChallengeResponseAuthentication setting to yes:

     ChallengeResponseAuthentication yes
  4. Configure authenticator for the user by logging in as the user and running: google-authenticator.

    • Answer y to time-based tokens. Then scan the barcode into your OTP authenticator app.
    • You should make a note of the Secret Key and emergency scratch codes
    • Answer y to update your .google_authenticator file.
    • Answer the remaining questions as you want.
  5. Now restart the SSH server to pick up these changes:

    sudo service ssh restart
  6. Log out and log back in. You will be prompted for your verification code before you connect.

     % ssh chris@aaa.bbb.ccc.ddd
     Verification code:
     Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-29-generic x86_64)

Passwordless auth

If you regularly connect from a single machine you might want to enable public key authentication.

sudo nano /etc/ssh/sshd_config

Find PubkeyAuthentication make sure it is set to yes

PubkeyAuthentication yes

Restart the SSH server to pick up the change:

   sudo service ssh restart

Now log out of the server, you need to push the public key from your local machine.

Copy your public ssh key to the server

This assumes you already have a key pair on your local machine. If not see here for a more detailed description of setting up key based authentication on Ubuntu 20.04

ssh-copy-id chris@aaa.bbb.ccc.ddd

Remember, just change chris to be the username you have set up. You’ll see a message saying the local computer doesn’t the server, just type yes and hit ENTER to continue. Finally enter your password (and verification code if you’ve setup 2FA), hit ENTER and your public key will be copied to the server.

You should now be able to connect to the remote server without providing the remote account’s password.

ssh chris@aaa.bbb.ccc.ddd

Install fail2ban


fail2ban is a UNIX service (daemon) that automatically detects malicious behaviour and bans offenders by updating the firewall rules. Basically once fail2ban identifies a malicious user they can’t connect to the server at all, requests to connect go unanswered until the ban is lifted.

sudo apt-get install fail2ban
Manage fail2ban

Once fail2ban installs you can check the service Status

sudo service fail2ban status

To start/stop or restart fail2ban:

sudo service fail2ban (start|stop|restart)

You’ll need top restart it if you change its configuration.

List Banned offenders
sudo iptables -L f2b-sshd --line-numbers


Chain f2b-sshd (1 references)
num  target     prot opt source               destination         
1    REJECT     all  --     anywhere             reject-with icmp-port-unreachable
2    RETURN     all  --  anywhere             anywhere            

Here we are listing only the rules in the f2b-sshd chain. If you want to see everything simply run sudo iptables -L --line-numbers

Remove ban
sudo iptables -D fail2ban-ssh <Chain num>

So to unban from example output above:

sudo iptables -D fail2ban-ssh 1
Configure fail2ban

A full description of fail2ban configuration is beyond the scope of this article. However the main configuration file /etc/fail2ban/jail.conf which you should never edit directly. We’ll add some overrides in /etc/fail2ban/jail.local

sudo nano /etc/fail2ban/jail.local
  1. I think the default ban time is too short, 8h should deter most people.

  2. Ignore any IP address that I own which do not change often (like my home IP address) and the server itself.

  3. Enable the jail for sshd.

     bantime = 8h
     ignoreip =
     ignoreself = true
     enabled = true

Now restart the fail2ban service:

sudo service fail2ban restart


What have we done?

  1. Configured an admin account with sudo permissions so we don;t have to use root account

The steps above are the minimum precautions I take when spinning up a publicly accessible server. I should point out I’m no security expert nor a Linux admin so there are doubtless many other tweaks and settings that could be changed


Book your free consultation

We’ll work together to understand your needs and develop a proposal and price estimate.

Book Now