Improve SSH security (How to secure a web server – Part 1)

In this series of tutorials we’ll take a look at basic server security, and in this first article we’ll learn how to improve SSH security. Any machine connected to the Internet immediately becomes a potential target to any kind of attack (hackers, automatic bots, …). Security is somewhat less of a concern for regular Web hosting (shared hosting or managed hosting for example), as most of it is managed by your hosting provider. Servers that you fully manage, however, come with absolutely no security out of the box. This is the case for most dedicated servers, VPS (Virtual Private Servers) and Cloud platforms (AWS, Google Cloud, …).


For this series of tutorials, we’ll assume you already have a server available. This tutorial uses a $5 Digital Ocean Droplet, but the steps described will work on any server running Ubuntu 16.04. Other distributions should work pretty much the same, to some extent.

If you’re interested in setting up a Digital Ocean Droplet, you can use this link to get a free $10 credit. This will give you 2 months of the 1GB RAM Droplet for free!

This series also assumes a basic understanding of Linux systems and the command line interface, as we’ll exclusively be using the command line.

Also note that the advice given in this series is not in any way a guarantee of the security of your server. It is only meant to give a basic overview of the first steps to take in order to secure a server.

Make sure to read our other articles in this web server security series:

Improving SSH security

This first article will focus on setting up SSH on our server. SSH is used to connect to and gives you full access to your server, by running commands as you do on your local machine.

This also means that SSH can be a huge risk factor if not set up properly. A basic Ubuntu installation on a Digital Ocean Droplet, for example, comes with SSH enabled for the root user, with only password authentication (unless you set up a SSH key, which you should). So if you don’t change that, anyone can potentially brute-force your root password and get full access to your server.

Let’s see how we can improve SSH security!

SSH key-based authentication

SSH key is the method we’ll use to authenticate on our server when connecting with SSH. It works as a pair of keys: a public key, that you’ll put on the server, and a private key that will stay on your local machine. You should never share your private key with any machine or person!

Basically, when you’ll try to connect to your server, the server will send an encrypted message to your machine, that can only be decrypted using your private key. Once your machine decrypts the message (or challenge), the server knows that you are authorized to connect, and will start the secure session.

Generate a key

Use the following command to generate a 4096 bits rsa key:

  • -b: size of the key in bits
  • -t: use RSA as a key type
You will be prompted to enter a path for the key. It defaults to ~/.ssh/id_rsa. It is best practice to use a separate key for each application, and for this example we will save the key as ~/.ssh/id_rsa_do.

Add the SSH key to your server

When creating the Droplet

Adding the SSH key is easily done when creating the Droplet. On the creation page, you’ll be able to copy-paste the public key. This will set up the server to use this key when you try to connect with SSH (but it will not disable password authentication).

On an existing server

If you already have a server running, you can add the SSH key by writing it to the authorized_keys  file in ~/.ssh. We’ll be creating a new user anyway, so there’s no need to set it up for root.

Create a new user and set up SSH

Connect to your Droplet via SSH

Click on the Droplet tab on Digital Ocean’s website. There, find its IP address and open a terminal on your computer. Login to your server with SSH, using the root password. For a Digital Ocean Droplet, it is sent to you by email when you create the server. If you added your SSH key when creating the Droplet, then you can just use it to authenticate.

Login using the command ssh [email protected]<ip_address>. If this is your first login, you will be prompted to change your password.

Create a new user

Later on we’ll disable root login. We need to create a new user that we’ll use instead of root. Type ~# adduser <username> to create a user (replace <username> by the username you want to use). You will need to enter a password for the new user.

Give root privileges to the new user

We’re gonna disable root login, but we still need to be able to run some commands as root. For this, we need to add our new user to the group “sudo”. This will allow us to run commands as a superuser using sudo:

usermod -aG sudo <username>

-aG stands for “append to group”.

Add the public key to the authorized keys for the new user

Copy the content of the public SSH key file we generated earlier (, and paste it in the authorized_keys file on the server. To do so, login as the new user on the server. Assuming you’re still connected as root using SSH, type su - <username>. This will log you in as the new user and take you to your home directory.

As your user is new, it most likely won’t have a .ssh folder. Create it by typing mkdir ~/.ssh. Change the permissions on the folder to 700 (restrict access to this user only) by typing chmod 700 ~/.ssh.

Then create the authorized_keys file by running nano ~/.ssh/authorized_keys. If the file already exists, this will just modify it. Paste the content of the file into the nano editor. Then hit Ctrl+X to quit, then Y and enter to save.

Disable password authentication on SSH

To avoid the risk of someone finding and using your password to connect via SSH, let’s disable password authentication. This way you will only use your SSH key to connect, making it impossible for someone who doesn’t have your private key to connect.

Check SSH key-based authentication

Before disabling password authentication, it’s a good idea to check that the key-based authentication was set up properly. Open a new terminal on your computer (stay logged in in the 1st terminal just in case), and SSH into your new user’s account by running ssh <username>@<ip_address> -i ~/.ssh/id_rsa_do. The -i specifies which SSH key to use (it will use id_rsa by default).

You should get logged in immediately, without having to enter a password. Otherwise, the SSH key setup has failed; try doing it again and post a comment below if you need help!

Disable password authentication

Edit the sshd_config file, as the new user sudo nano /etc/ssh/sshd_config.

Find the line with PasswordAuthentication (use Ctrl+W in Nano). Make sure it is un-commented (remove # from the beginning of the line if it’s present), and set its value to “no”.

Also make sure that PubkeyAuthentication is set to “yes”, and ChallengeResponseAuthentication is set to “no” (it should be the case by default):

Disable root login

Still in the file /etc/ssh/sshd_config, find the line with PermitRootLogin and set it to “no”:

Change the SSH port

This one won’t really make any difference as anyone can still scan for open ports on your server using a tool such as nmap, but it can make it a little bit harder to figure out which port you are using for SSH. Find the line with Port and set it to a number of your choice (avoid numbers under 1024, as they can be reserved for other applications):

Again, this will not prevent an attack from someone who knows what they’re doing. But it could prevent a stupid bot from brute forcing into port 22 (standard port for SSH). Using another port could also make it look like an application port to an attacker who scans your open ports; they would probably not think at first that you use port 1234 for SSH.

Only allow SSH access to your new user

At some point you will most likely have to add users to your server (FTP, email, …), and they will be able to login with SSH. To prevent that, you can add a list of users allowed for SSH. Any user that’s not in the list will not be authorized to connect. Find or add the option AllowUsers:

You can also deny users access using the option DenyUsers, although this is not really useful if you already use AllowUsers.

Reload the SSH configuration file

To apply the changes to SSH, reload the configuration file by running sudo systemctl reload sshd.

Test it

The test cases we have to check are the following:

  • Connect as root – Should fail because root user is not allowed

  • Connect as your user on standard port (22) – Should fail because we changed the SSH port

  • Connect as your user on correct port, with incorrect SSH key – Should fail because of incorrect SSH key

  • Connect as your user on correct port, with correct SSH key – success!

Automated scripts

Here is a set of scripts that will create a user and setup SSH, as well as an example of a SSH configuration file. Make sure to change the username in this file, and the SSH port if you want to change it:

The expected folder organization is:

  • files
    • sshd_config
    • (public key file)

You must copy your public SSH key file to the “file” folder before running the scripts.

Copy the folder scripts to your server (assuming you are still using user root with password authentication for SSH, otherwise there’s no need to use those scripts!):

On the server as root, run them as shown below (assuming you are running them as root, otherwise you’ll have to prefix the commands with sudo):

<public_key> is the absolute path to your SSH public key.

At the end of this series we will have more scripts to automate the other steps, this way running only one script ( will set up everything we need.


We’ve learned how to set up our server to use key-based SSH authentication, and disable root login. That’s a big security improvement, but there’s still a lot of other things we can do. In the next article of this series we’ll learn how to set up a firewall on our server to block unwanted connection attempts.

Please feel free to share this article and leave a comment below if you need more help!

Be the first to comment

%d bloggers like this: