Secure a Debian-based server

In this guide, I’m gonna show you how to secure your server with:

Step 0 : Requirements

This guide assumes you already have a working server with SSH installed both on your computer and on the server.

Step 1 : Change the default passwords

The best option for that would be to use a random password generator and a password manager.

passwd
sudo passwd

Step 2 : Add your ssh key

This will prevent other people than you to access the server (with the next step as well), even if they know the password. So run the following commands on your computer to generate a key:

ssh-keygen -t ed25519 -C "<your email address>"
ssh-copy-id <user on the server>@<ip address of the server>

Step 3 : Disable password authentication

This will disable basic password authentication, so only people with verified keys and correct password will get access to the server. After changing the configuration, we’re going to restart ssh.

sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
sudo sed -i 's/ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/g' /etc/ssh/sshd_config

sudo systemctl restart sshd

Step 4 : Install fail2ban

Fail2ban will block people that try to get into your server. You just have to install it, we’re going to use the default configuration file.

sudo apt install fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

Step 5 : Install ufw (firewall)

We’re going to install ufw, which is a firewall rule parser.

sudo apt install ufw

Step 6 : Configure new rules with ufw

We’re going to disallow any connection, except from three parts.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow www
sudo ufw allow 443/tcp
sudo ufw enable

Step 7 : Install “let’s encrypt”

This will install the tool to get the HTTPS certificates for our domain name:

sudo apt install letsencrypt

Step 8 : Certify the domain name

Now we can use “let’s encrypt” to create our certificate, but we first need to stop nginx and/or apache2.

sudo systemctl stop nginx apache2
certbot certonly --standalone -d <your domain name>
sudo systemctl start nginx apache2

Step 9 : Move the configuration file

We’re going to overwrite the default nginx configuration file, so let’s backup the existing one.

sudo mv /etc/nginx/sites-available/default /etc/nginx/sites-available/old
sudo nano /etc/nginx/sites-available/default

Step 10 : Creating the default configuration

You just have to paste the following configuration and change the relevant information:

server {
    listen 80;
    server_name <domain> www.<domain>;
    return 301 https://<domain>$request_uri;
}

server {
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
        server_name _;
        location / {
                try_files $uri $uri/ =404;
        }
}

Step 11 : Restart nginx to apply the configuration

Congratulation, you now finished this tutorial, you’ll just have to restart nginx for your last changes to take effect:

sudo systemctl restart nginx

Conclusion

Congrats! You now secured your server, to summarize, you now have: