This tutorial covers the first three steps to secure any Linux server. Be it a VPS, Linux Virtual Machine, or a raspberry pi. These steps will work for any Debian-based Linux distribution, However, other Linux distributions should use similar commands.
The three steps in this tutorial should be the bare minimum you need to secure a Linux server. This is in no way a complete server hardening guide. Researching for this tutorial, I noticed a lot of other blogs start with “Update your Server”. This tutorial is going to be different assuming your server is already fully updated and upgraded (apt-update apt-upgrade) before reading.
Also, make sure you are always using Secure Passwords. Get yourself a password manager if needed!!!. You only have to take a look at my tutorial Brute Forcing Passwords with THC-hydra to see how easy this type of attack is to perform.
Step 1: Create a New Sudo User
Normally, when you first get logged in to your shiny new Linux server. You will find yourself logged in as some sort of default user or worse ROOT. This is very insecure, especially for everyday use. The best option is to create a new custom user and making them a member of the sudo group. This approach is much more granular for user security, stopping an admin, accidentally running something and inadvertently breaking the server.
This is especially helpful if you have multiple admins accessing the server at the same time. Even though, Out of the scope of this tutorial, Sudo can be customised to a particular user. Giving admins only a subset of commands they need to run with root privileges.
Recently, a lot of Linux distributions do not set a root password during installation. Therefore you don’t get the facility to log in as root by default. If this is you, either stick around and create a new Sudo user or skip to Step 2.
- Firstly, start by creating a new user with the adduser command, then type the username you want to create. In the example below, I create a user called securitytutorials.
- Then, you will be prompted to set a password for the new user, retyping it a second time to confirm.
New password: Retype new password: passwd: password updated successfully
- Next, enter some information about the new user. However, you can hit enter at each step, to skip through them. Then select Y to confirm all the information is correct.
Changing the user information for securitytutorials Enter the new value, or press ENTER for the default Full Name : Room Number : Work Phone : Home Phone : Other : Is the information correct? [Y/n] Y
- Now we need to add the new user we just created to the sudo /sudoers group. Using the usermod command with the -aG options to append to Group sudo. Then add the new user name you just created.
usermod -aG sudo securitytutorials
- It’s now time to test everything is working. Switch users by typing su and the name of the user you created.
- Once you have switched to the new user, you need to make sure sudo is working correctly. Run any command with sudo in front of it, to test.
If the sudo test completes successfully move onto Step 2. If not, check all the steps above before moving on. In Step 2 you will be disabling root ssh access, progressing further without sudo or root access could cause issues.
Step 2: Setup SSH Key Based Authentication
Step 2 covers setting up SSH Key-based authentication, disabling password-based Authentication and disable login to SSH as a root user. If you check your SSH logs, you will probably already notice failed logon attempts as a root user. These steps will add an extra layer of protection to your SSH server.
Now, this tutorial only covers the basics of securing SSH. If you want to read something more in-depth, Check out my Secure Shell (SSH) tutorial.
- Using ssh-keygen, start by creating your public and private key pair. Use -f to specify a name and where you want to save the key, -t states you want to generate an RSA key and finally -b to specify using 4096-bit encryption.
ssh-keygen -f ~/.ssh/Ubuntutest -t RSA -b 4096
- Hit enter, you will be asked to enter a secure passphrase for the Key. You can just hit enter again here to skip entering any password. I do, however, highly recommend using a passphrase here, adding extra security to the SSH key if they were ever to get compromised.
ssh-keygen -f ~/.ssh/Ubuntutest -t RSA -b 4096 Generating public/private RSA key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/hemp/.ssh/Ubuntutest Your public key has been saved in /home/hemp/.ssh/Ubuntutest.pub The key fingerprint is: SHA256:2qgotyJYh1l9HahP055Jj6LTWdN3zr15fPxogl1gQhU [email protected] The key's randomart image is: +---[RSA 4096]----+ | . .E. | | . o | | . . + . | | . o + = o | | + +S+ O . | | + . +o B o o .| |.. . oo.+ + o *.| |= .. .o o . o ..X| |.+o.. . o.o*| +----[SHA256]-----+
- Once complete, you will have two files, in the location, you specified in the previous command. One of the files will have a .pub extension, this is the public key. In contrast, the key without any extension is the private key.
Note: Make sure, to always keep the private keys safe. Only ever give out your Public key, as the Private keys are like having “the keys to the castle”. If someone got access to them and no password was set, they would gain full access to your server.
- Now, it’s time to copy the public key to your server. Using ssh-copy-id, specify the location of the public key with a -i and connect to the server with the user you created in step 1.
ssh-copy-id -i ~/.ssh/Ubuntutest.pub [email protected] /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/hemp/.ssh/Ubuntutest.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys [email protected]'s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '[email protected]'" and check to make sure that only the key(s) you wanted were added.
- Test the keys have been added correctly by connecting to the ‘ssh server using -i again, this time pointing to your private key. If you specified a passphrase when creating your key, you will be asked to enter it now.
ssh -i ~/.ssh/Ubuntutest [email protected]
Note: The next few steps, cover turning off Password-based Authentication. Meaning that you will no longer be able to connect to the SSH server without using the private key we just created. Hence, if you lose the private key, you will no longer be able to log in via SSH.
- To turn off Password-based Authentication, we need to make some changes to the sshd_config file. Using sudo and the text editor nano, open the sshd_config file located in /etc/ssh/.
sudo nano /etc/ssh/sshd_config
- In the sshd_config file, uncomment both the lines below by removing the # from the front of the line. In addition, make sure PasswordAuthentication and PermitRootLogin are set to no. Once all set hit control + x to save the changes.
Note: The PermitRootLogin being set to no stops the root user from being able to log in via ssh. Make sure you have at least a tested sudo user from Step1 before setting this.
PasswordAuthentication no PermitRootLogin no
- Now, restart the sshd service for the changes to the sshd_config file to take effect.
sudo service sshd restart
- Log in via SSH again, Just to make sure everything still works..
ssh -i ~/.ssh/Ubuntutest [email protected]
Step 3: UFW (Uncomplicated Firewall)
Finally, firewalls allow you to manage, what and who has access to the ports on your server and is a must for any Internet-facing server. Most Linux distributions come with the firewall disabled by default, this probably is due to the expertise needed to configure it. Just google “configuring Iptables” and you will understand. That is where UFW (Uncomplicated Firewall) comes in. UFW is an easy to use firewall consisting of only a small number of commands, taking all of the pain out of configuring firewall rules with Iptables.
In Step 3 we are going to cover, enabling UFW and allowing the SSH ports. Likewise, If you need to allow extra ports like HTTP, HTTPS or SMTP it’s the same process. Many Linux distributions like Ubuntu, come with UFW pre-installed. However, if you don’t have it UFW can be installed with sudo apt install ufw.
- Firstly, UFW is inactive by default, before it gets enabled make sure you open port 22 (SSH). Otherwise, you will become disconnected once it gets enabled. Type “sudo ufw allow” then either type the port number “22” you want to allow or the name of the service “ssh“.
sudo ufw allow ssh or sudo ufw allow 22
Note: Use the above command to open any other ports you need either, directly using a port or by service name.
- Next, it is a good idea to enable logging in UFW. Type sudo ufw logging on to enable logging. Furthermore, the logs are located in /var/log/ and start with a ufw prefix.
sudo ufw logging on
- Now it’s time to enable UFW. Make sure you at least have the port for SSH open before proceeding to enable UFW. Type sudo ufw enable, then type y to proceed.
sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
- Once UFW is enabled, check at any time which ports are open by typing sudo ufw status.
sudo ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6)
What Next !
As stated at the start of this tutorial these three steps are just the basics you need to keep a Linux server secure. Depending on what you are running on your server extra hardening steps might be needed. However, if you are looking for something else to do… how about setting up an automated backup with Rsync? or setting up an Intrusion prevention system with fail2ban?
I left out changing the ssh port from this tutorial because I wanted to keep things simple. but, you can easily edit the sshd_config and change the default port. With this in mind, remember to first open the port you want to change SSH to in UFW first.
Whatever you do decide, please leave me a comment below. I love to know if you have questions or queries or just to tell me your top three tips for securing a Linux server.