Ubuntu Hardening Guide – Basic (QGR)

In the past few weeks we have gone through setting up a LEMP stack on Ubuntu to run our WordPress site.

As this is a web server and will be exposed to the internet we need to make sure we do some additional configuration regardless of if it sits behind a Next-Gen Firewall, or Web App Firewall. Perimeter security is no longer sufficient, we need to harden the operating system to provide some strength in depth.

Now you shouldn’t look at this as an all or nothing situation, or that hardening the operating system is something you do once and that’s it. You can start with the basics which greatly reduces your exposure, but it needs to be monitored and maintained over time.

I start with the basics and then dependent on the resources available and the value of the server/data I make improvements over time, this is a great way to learn.

Below are some resources for further information on hardening Ubuntu.

Ubuntu Hardening Wiki


NCSC Hardening Guide


UFW guide


As this is a quick guide we won’t be going into too much detail for each setting, but as always I encourage you to look into this yourself so you understand what we are doing.

In-depth SSH keys guide


Bitvise download


The steps we will take are;

  • Enable ufw. This is a built in host-based firewall.
  • Install fail2ban. This is an intrusion prevention system (IPS) which looks for patterns to identify attacks and block the offending IP addresses.
  • Secure shared memory. Shared memory can be used to attack running services so we need to secure it.
  • Create a non-root user, and grant sudo privileges.
  • Enable key pair SSH login.
  • Disable SSH password authentication and root ssh login.
  • Disable any graphical User interface. (X11 Forwarding)
  • Disconnect idle sessions.
  • Allow/Deny users

Make a back up

Make a back up, now we can continue.

Enable ufw

This configuration is based on the assumption we are using port 22 for SSH, and have ports 80 and 443 open for web services.

ufw is installed by default so you can just enable without the need to install.

sudo ufw enable

And open the 2 ports we need for connecting to it

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

You can check status using the below

sudo ufw status


First up, let’s install.

sudo apt-get install fail2ban

fail2ban will work right out of the box, but we can make some small adjustments. Rather than make changes directly to the default config file located at “/etc/fail2ban/jail.conf” we can create a new file named jail.local using the following command.

sudo nano /etc/fail2ban/jail.local

Then add the following to the new file.

enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 5

This monitors for brute force login attempts on port 22, now just save and close the file then restart fail2ban

sudo systemctl restart fail2ban

Remember that this will also block YOUR IP if you fail 5 login attempts. You can adjust the time out settings in the “/etc/fail2ban/jail.conf” file.

Protect shared memory space

We need to edit the /etc/fstab file and make a settings change.

sudo nano /etc/fstab

Now we add the following line to the bottom of the file, before saving and closing.

tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0

This will require a restart which is a simple command.

sudo reboot

Create non-root user with sudo privileges

Logging into your Linux box as root and using it as your everyday account is the same as just using the domain admin or local administrator account as a normal user account. If you don’t understand how bad this is you should go find out!

We will create a standard user account but grant them sudo privileges so you do not have to log out each time you need root. You will able to use the ‘sudo’ command enter a password to elevate to the needed permission level. Let’s get started.

Log in as root and run the following commands picking your own username

adduser newuser

Choose a strong password, and then answering the other questions are optional. Next we assign sudo to the new user.

usermod -aG sudo newuser

That’s it. If you want to change user just use (replace newuser with the desired username)

 su newuser

Enable key pair ssh login.

This is much more secure than password authentication, and again if you do not understand why, I really encourage you to go and find out. As most of you will be connecting to your server via Windows machine I’ll cover setting this up using an ssh gui client, however if you are connecting from a Linux box follow the link in the resources section for a quick way to perform this process via command line.

I’m a fan of Bitvise ssh (link in resource section above) and from here we can easily create our key pair from the login tab and selecting “Client key manager”.

Generate new as shown

Make note of the profile number, and choose a strong passphrase. You can choose a larger key size if you wish but do not go lower.

Now below we can see our new key, and the export button to create a file of our public key.

Export as shown below and remember where you have saved it.

Now login to your Ubuntu machine using your new account and check for the ssh directory, and if we don’t have one we need to create it. The following command will create the directory if it does not exist and do nothing if it does.

mkdir -p ~/.ssh

Now browse here using cd and locate the “authorized_keys” file.

cd ~/.ssh

If “authorized_keys” file is not there then create it

sudo nano authorized_keys 

No go back to your exported file on your local machine and paste the contents into the new file on your Ubuntu machine. This file should start with “ssh-rsa”, then save and close the file.

Now we set permissions making sure you replace “newuser” with your own username

chmod -R go= ~/.ssh
chown -R newuser:newuser ~/.ssh

Now we need to test that this works, so disconnect from the remote session and attempt to login using public key authentication instead of a password. In Bitvise select the correct profile, and pubkey as shown. Obviously you will need the username and host address to connect.

The first time you connect you will receive a warning about key verification, but as long as you are sure you are sure you connecting to the correct host you can accept this the first time you connect. Should you ever see this error again when connecting to this machine you should verify the keys to ensure you are not a victim of malicious activity.

You will then be prompted for the key pair passphrase (not your login password), enter this and you should be logged in. Well done now we need to disable password authentication, and root ssh login.

Disable password authentication and root ssh login

This is a quick and simple one, we just need to edit the sshd_config file and set the options to no.

sudo nano /etc/ssh/sshd_config

Disable any graphical User interface. (X11 Forwarding)

This is set in the same file, find the option and set to no

Disconnect idle sessions

Again, in the same file change the following settings

This setting will check once after 15 minutes of inactivity and close the connection. If you want a longer interval just increase the setting which is in seconds.

Allow/Deny users

Again in the same file we can provide an allow list of users who are permitted to remotely connect over ssh to the machine. You will need to add this manually to the bottom of the file.

Make sure there are no typos and you have added everyone you need to as once this is set if not on the list you will not be able to login via ssh and may be completely locked out of your server. Double check before loading the new config.

To load the new settings we need run the following commands.

sshd -t 

If you receive an error go back and check you changes as you have made a mistake somewhere. If not then restart the service to apply the changes.

sudo service sshd restart

Well done, in the future we will look at more advanced hardening techniques.