Codementor Events

How do I secure a Server?

Published Aug 02, 2021

Writing this, I know that there will be a bunch of alternatives out there, and they are all probably good as well, but there are definite things that you need to care about, so if they don’t do it then at least ask the question “why”.

This guide is not meant for someone who is using managed hosting. Managed hosting is a quick and easy way to get a server set up for you (usually using cPanel, DirectAdmin, etc.) however, you pay for this convenience. The nice thing about it, is you get to trust that the web host knows what they are doing and they need to keep a close eye so you don’t need to.

However, with so many sites being built nowadays, there is a push to go to your own Virtual Private Server (VPS) that can be hosted pretty much anywhere. You pay less, because you take on the burden of maintaining and securing the server. Some examples of these hosting options are below:

Anyways, back to business, when setting up a web server, there are a few things that you need to take into consideration. First and foremost, access to the server. Given that it needs to be available on the internet, the normal way you would connect to it would be through SSH (secure shell). Unfortunately, your’s and a good chunk of other servers on the internet use SSH, so although it’s great, if you don’t set it up correctly, you are vulnerable to attack.

Please Note: I will be walking through the process that I use for a Ubuntu/Debian server. There are similar options out there for Centos and every other flavour out there.

To rectify this issue, I do the following:

1. Disable “root” login via SSH

Default system accounts (i.e. root, ubuntu, etc.) are well known to potential attackers, they snoop through all of the IP addresses on the internet looking to see if they can use password authentication in order to connect to your server. The sad thing is, these brute force attacks work! There are lots of servers out there that have been affected by it and are then used as a workforce to help brute force other servers (as well as other malicious deeds).

As a prerequisite for this, you will need to create another account on your server which has been granted admin rights.

Install “sudo”. This program allows you to run a command as another user, i.e. you connect to your server as your user account, and then run something as the main root account. To do this, you will need to do the following as the “root” user:

apt-get update # Updates the software libraries which are available
apt-get upgrade # Make sure you have the latest and greatest versions
apt-get install sudo -y # Install the “sudo” application

Now that sudo is installed, we need to create another user account:

adduser site # You will be prompted for information, just fill it in (site is the username)

Now that the “site” user has been created, let’s grant them access to the “sudoers” group (a special group made to grant people access to the “sudo” command).

usermod -a -G sudo site # Adds the user to the group

Now, test that you can use “sudo”

su site # Change your current account to the “site” account
sudo bash # Attempt to run bash as root

If this all works, you are now in a spot where you can disable root access. And this action is surprisingly simple! As root, you will need to modify the following file: /etc/ssh/sshd_config. To do this, you will need to do the following:

nano /etc/ssh/sshd_config # This will open a text editor

Within this file, look for the following line:

PermitRootLogin yes

Or:

PermitRootLogin prohibit-password

And change it to the following (there may be a “#” sign in front of this line, if that is the case, then remove that character as well):

PermitRootLogin no

This will remove the ability for someone to login as “root” after you reload the configuration. So, to do that, you will need to do the following:

/etc/init.d/ssh restart # Restart the SSH service

Great! The last thing to do is verify that the changes you made have taken effect. The good news is, this test is really easy to do! Since you are already connected with the “root” account, just repeat the same method that you did the first time to connect, and it should fail! If it doesn’t, then one of the settings may not be set up correctly.

Please Note: While on this step, I normally keep my original SSH connection open and test one last time that I’m able to SSH in as the other user (i.e. site) and then run sudo commands. If I am not, I have effectively locked myself out of the server as well which defeats the purpose of what we are trying to do!

2. Disable password login via SSH

Wait! You want me to disable password logins? How will I be able to connect to the server and do stuff?

This is where a thing called “SSH Keys” comes into play. They are a way that you are able to generate a “lock” that only your key can log in with. The really neat thing about these keys is you can actually use it to authenticate to any of your servers (if you set it up correctly), but that also comes at a risk. If your key is compromised, then your attacker has access to all of your servers. Personally, I think this tradeoff is acceptable as long as you keep it in a secure spot.

So, SSH into the server as the “site” user (or the user that you set up while walking through this), and type in the following:

ssh-keygen # A tool to generate SSH keys

When you type this in, you will be prompted as follows:

Generating public/private rsa key pair.
Enter file in which to save the key (/home/site/.ssh/id_rsa):

You are fine with just hitting enter at this point. Then you will be prompted for a passphrase. This is another safeguard that you can take to ensure that even if your private key is in the hands of a nefarious person, you are still safe. This is adding a password to it, so add one in.

Great! You now have a SSH key generated! This process generated two files:

  • id_rsa - Your private key, keep this in a secure location
  • id_rsa.pub - Your public key, this is used on the authentication side to grant access

So, first thing’s first, let’s make it so that you are able to log in using this key. To do this, you can do the following:

cd ~/.ssh # Change into the “.ssh” folder
cat id_rsa.pub >> authorized_keys # Appends the contents of the file into an “authorized_keys” file which the SSH server will use to authenticate
chmod 700 authorized_keys # Restrict access to the file

Awesome! Now, the server is set up for ssh key authentication, now you need to make it so that your local computer can use this key to connect.

For starters, we need to get a copy of the key file. To do this, you can do the following:

cat id_rsa

This will print out the contents of the file to your screen, simply copy the output and save it on your computer.

On a *nix system (linux, or mac), you are able to put this file into the “~/.ssh/” folder on your computer, and it will automatically pick it up whenever you try to log in. So, all you need to do there is make a file “id_rsa” and save the file there. If you are on Windows, you are able to use Putty to handle this.

Now, the next step as always before we actually disable anything on the server is to make sure that you are able to SSH into the server with the newly created key. On a *nix system, you will then be able to do the following:

ssh site@domain.com # If you named it id_rsa

If you did rename the file (or put it in a different folder), you are able to use the “-i” flag in order to specify where to read the identity file from.

ssh -i ~/.ssh/id_rsa site@domain.com # Same as above

If set up correctly, you should now be automatically logged into the server (assuming you typed in the password correctly). If this doesn’t work, then you have an issue which should be resolved before moving on.

Now that we have successfully authenticated with this key, we are now able to make it so we don’t allow passwords to be used to log into it. You can do this by doing the following (from the SSH window).

sudo bash # Elevate your account to root
nano /etc/ssh/sshd_config

Now you are in the text editor again, you will need to change the following:

PasswordAuthentication yes

Change this (the line may be commented out) to:

PasswordAuthentication no

And then exit the editor like before, and restart the SSH service again:

/etc/init.d/ssh restart

Now, it’s time to test the new configuration (before you kill your SSH session). In a new window, try to connect with the ssh key you previously made, this should still work. The next thing you need to try is to connect without the SSH key, to ensure that no one will be able to. An easy way to do this is as follows:

ssh -i /dev/null site@domain.com

This will probably give you an error that the key is in an invalid format but this is fine, because it tried to load the non-default key, and would normally fall back to using password login. If it worked as planned, you should see the following error message:

site@domain.com: Permission denied (publickey).

If you got this, then great! Your server is only accessible by SSH key!

Please Note: if you have other people that need to connect to your server via SSH/SFTP (i.e. developers, make their own account and repeat the first grouping of steps that way if you need to revoke their access, you can do so by just removing their user account!).

3. Enable failure monitoring to catch potential attackers

Now that you can only log in with SSH keys, and root is no longer allowed to log in at all, you might be thinking, “hey, I should be safe”. Technically you are right, but at the same time, you have gone to all of this why not add a few other things to the list?

Brute force attacks can still be directed at your server, they are less likely to get anywhere, because they pretty much get no feedback about their authentication (rather than “password is invalid” without the key). But why not set your server up to keep an eye on suspicious login attempts and stop them on the spot without you even knowing?

This is what “fail2ban” will do for you.

sudo apt-get install fail2ban -y

The default configuration works however, if you want to tweak some of the settings, a great tutorial from Digital Ocean is available here.

4. Keep your server up-to-date

All software is written by people, every day there are updates going out to different packages. These include feature updates, as well as bug and security fixes. So, the best way to make sure you are safe is by keeping your server update-to-date!

sudo apt-get update
sudo apt-get upgrade -y # Update software

Just like your personal computer, from time to time there are patches and updates for the operating system as well, so you will want to keep those up-to-date as well. That being said there is a small risk that upgrades make take things down for a bit so do this one with a bit more care.

sudo apt-get dist-upgrade -y # Update operating system

5. Optional: Restrict SSH access to certain IP addresses

If you are confident that your IP address never changes, then you are able to lock your server down also to your IP address. Typically I avoid this just because I use public WiFi from time to time and would like to connect to my servers.

In order to do this, you can use iptables (built-in firewall) to restrict access on your SSH port. All you need to do for this is as follows:

sudo bash # Login as admin
iptables -A INPUT -p tcp --dport 22 --source 192.168.0.0/24 -j ACCEPT # Change 192.168.0.0 to your IP address/range
iptables -A INPUT -p tcp --dport 22 -j DROP # Ignore all other requests

By default, these rules are not saved and reloaded when you reboot the server. In order to do that you will need to install another program, and have it start as a service.

sudo apt-get install iptables-persistent # Installs persistent rules
sudo service iptables-persistent start # Start the service

Now, no matter what, your firewall settings should remain in place.

6. Optional: Change the default port to run SSH on

Most SSH servers run on the same port, 22. Because of this, if you want to make your server harder to find, you can always change the port that you connect on. This is also available through the configuration file.

You can do this by doing the following:

sudo bash # Elevate your account to root
nano /etc/ssh/sshd_config

Look for the line that says:

#Port 22

And change it to the following:

Port 1000 # 1000 is the port it would be connected to so change this however you would like

Once done, exit, save and restart the SSH server and you should be good to go!

/etc/init.d/ssh restart

Congratulations!

Your site should be relatively secure from the attackers of the world!

Original Post: TheGamingList

Discover and read more posts from Andrew Judd
get started