This post is free for all to read thanks to the investment Mindsers Blog's subscribers have made in our independent publication. If this work is meaningful to you, I invite you to become a subscriber today.
There are several reasons why a developer would want to manage their own servers. Servers, especially VPS (Virtual Private Server), have become very affordable resources. They allow us to test, build, host our projects and do many other things.
Whatever use you make of a server, it must be protected, because an intrusion could have serious repercussions. In this article, I explain how to secure a VPS simply in 5 simple steps.
1/ Update your system
This may sound basic to you, but one of the primary reasons for finding flaws in web servers is system obsolescence. Not updating your systems regularly is a real danger for your business.
Even if you have just requested the installation of your VPS from your host, you will benefit from updating your system before moving on to the rest of this article. Indeed, hosts often use backups or snapshots to create new servers. So, there is a good chance that the packages on your system need updates.
Run the following commands:
$ sudo apt update $ sudo apt upgrade -y
I'm not sure it's worth explaining. Change your
$ sudo su $ passwd New password: Retype new password: passwd: password updated successfully $ exit
root account is the “super-administrator” account. He has all the rights. If there is an account that we refuse to leave in the hands of hackers, it is this one.
But changing the
root account password is not enough. You will see that a little further in the rest of the article.
3/ Create a new user
Another tip to avoid problems on your server: don't use
root. I see at least two reasons for this:
- everyone has a
rootuser on their machine by default. It's easy for a hacker to guess
roothas all rights on the machine. If a person finds the root account password, he can do anything on the machine
The best solution to prevent this problem is to use a different account to manage your machine. To do this, use the following command:
$ adduser nameOfTheUser Adding user `nameOfTheUser' ... Adding new group `nameOfTheUser' (1001) ... Adding new user `nameOfTheUser' (1001) with group `nameOfTheUser' ... Creating home directory `/home/nameOfTheUser' ... Copying files from `/etc/skel' ... New password: Retype new password: passwd: password updated successfully Changing the user information for nameOfTheUser 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]
After answering all the questions of the utility, let's tell the system that this new user will be able to perform actions usually dedicated to the superuser without being one.
The idea is to be able to say “I'm not a superuser, give me no rights” but temporarily, when the situation requires it, tell the system “in fact, I'm the superuser, let me do this one-time action”.
$ adduser nameOfTheUser sudo sudo adduser nameOfTheUser sudo Adding user `nameOfTheUser' to group `sudo' ... Adding user nameOfTheUser to group sudo Done.
Now you will be able to type the
sudo command from your new user account without receiving a system denial. You can also connect in SSH directly with this user.
4/ Change SSH access
Now that only you know the password for the root account, and you no longer use it to connect to the server, it's time to go a little further.
What are the problems we might encounter? Brute force attack. You no longer use the
root account, but it is still usable. Using randomly generated passwords until one works is a method that still works today.
The method would also work on the second account that we created above.
To remedy this, we'll modify the SSH configuration somewhat to log in using an RSA key rather than a password. To be able to log in with a key, you first need... a key.
So let's generate ours on our local computer (not the server).
$ ssh-keygen -t rsa -b 4096 -C "email@example.com"
-tallows you to indicate the type of key you want to create. We want an RSA key.
-bspecifies the size of the key. I usually put 4096 so that it is twice as long, complex and solid as the default 2048 bites. But, you can put the size you want. Just tell yourself that depending on the power of your computer, the more you ask for a long key, the longer it will take to generate (and use?) it.
-Callows you to add a comment to facilitate your organization.
The command will ask you for a passphrase. It is a sentence that must be indicated to use the key. A kind of password to protect the key. You can leave it out, but it is strongly recommended that you do put one.
Once the key is generated, you will find two new files on your local machine.
$ ls ~/.ssh id_rsa id_rsa.pub
id_rsais your private key. Not to be communicated under any circumstances. It must not leave your machine and allows you to decrypt the data that is sent to you.
id_rsa.pubis the public version of your key. To communicate to those with whom you wish to communicate. It does not make it possible to decrypt the data, but only to encrypt them. In other words, it allows people to write messages that only your private key can decrypt.
As I just said, the private key will not move from your machine. However, to be able to communicate with the server, the server must have your public key. So, we have to send it to him.
No need to open the file and copy-paste anything, there's a command for that:
$ ssh-copy-id -i ~/.ssh/id_rsa nameOfTheUser@ipOfTheServer
This command will create the
~/.ssh folder in your user's account on the server. Then, it will create the file
~/ssh/authorized_keys in which it will add the public key linked to the private key
Normally, this command sends all public keys from your local machine to the server. To avoid this, we use
-i to tell it which key to send.
You can now connect without passwords to the server by doing
ssh nameOfTheUser@ipOfTheServer. Only the passphrase will be requested if you have specified one.
Since it is possible to log in without passwords, all we have to do is disable the login with passwords. Thus, the risk of brute force will be eliminated. To do this, on the server, edit the following lines in the
/etc/ssh/sshd_config file to have these values:
PasswordAuthentication no PubkeyAuthentication yes PermitRootLogin no
With these settings, it will be impossible to log in with the root account whether you know the password or not. All other accounts will be inaccessible with a password, but accessible if you have the correct RSA key.
Last detail, the standard port used by SSH is 22. It means that everyone knows this port. To make the access a little more complicated, a good practice is to change this port to a value between 1024 and 6665.
In the same
/etc/ssh/sshd_config file, modify the following line with the value of your choice:
To validate these changes, restart the SSH agent as follows:
$ sudo systemctl restart ssh
Your server now looks a bit more like a fortress.
ssh nameOfTheUser@ipOfTheServer will no longer work. You will need, in addition to the user and the IP, to indicate the port that you have chosen previously. The password will not be requested, you will need the RSA key to be able to connect.
$ ssh nameOfTheUser@ipOfTheServer -p 2345 -i ~/.ssh/id_rsa Enter passphrase for key '~/.ssh/id_rsa':
5/ Enable a firewall
The firewall allows you to control who can connect to your server and how. The idea is to avoid leaving windows open in our fortress. We will therefore explicitly specify what we allow as a connection to our server.
Most Linux distributions have
ufw installed by default. I use UFW. I will therefore explain to you the basic rules that I apply for the security of my servers. To learn more about how this tool works, I recommend this article from DigitalOcean.
We start by disabling the firewall while we make our changes:
$ sudo ufw disable
Next, I change the default rules so that all incoming connections are denied, and all outgoing connections are allowed:
$ sudo ufw default deny incoming $ sudo ufw default allow outgoing
Next, we'll allow SSH connections. Otherwise, we will no longer have a way to connect to the server.
$ sudo ufw allow 2345/tcp
2345 to the port you chose for SSH in the previous step.
ufw allow ssh. But don't use it for SSH precisely, because you no longer use the default port 22. You risk blocking all SSH connections since SSH no longer listens to port 22.
Now we can activate the firewall.
$ sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
As we no longer use the default SSH port, if you still have connections using port 22 (on another terminal, for example), UFW warns you that you may lose your connection.
ufw status verbosecommand.
Now you have all the basics to secure your servers. There are of course many other things that one can implement to secure a server, but with the 5 steps in this article, you will have a server that is much less vulnerable to attacks.
I have also prepared for those who wish it a print which includes all the commands of this article, a glossary and an explanation of the changes of the
sshd_config file. Nothing more than what is in this article, but the idea is to have a cheat sheet to quickly secure your server.
If you are a premium member of the blog, download it below. Otherwise, you can find “VPS/server security cheatsheet” on the store.