Web Server

In this section, we deploy the nginx web server and the Certbot program that helps us with encrypting web communications.

Installation

nginx is a web server that we'll be using as a reverse proxy. That means nginx will sit between the client that makes a web request and the application server that responds. nginx will be responsible for encrypting the data sent via the open web between your clients and server.

Certbot is a program that automatically requests, configures, and renews the TLS certificates that nginx uses for encryption.

Install both of these, along with the plugin that makes them work together.

$ sudo apt install nginx certbot python3-certbot-nginx

nginx Configuration

Before you can verify that nginx is working, you will have to allow web traffic in through the firewall. This is safe to do because nginx by default responds to all requests with a static welcome page.

$ sudo ufw allow "Nginx Full"

In your browser, access http://your.domain.tld to verify nginx is running. You should see the welcome page. Note that throughout this process, since we haven't configured TLS yet, your browser might complain about a missing TLS certificate. That's expected and we will fix it a little later.

Next we're going to configure a virtual host to respond to requests to our domain. There are many safe and effective ways of doing this. I'll explain my usual method here, but feel free to do things differently if you prefer.

Create a new virtual host configuration file at /etc/nginx/sites-available/your.domain.tld.conf. This file will configure nginx to respond to every HTTP request with a 204 No Content code. This is not an error code. It means the client's request succeeded and the server's response intentionally contains no data.

server {
    server_name your.domain.tld;
    location / {
        return 204;
    }
}

Disable the nginx default virtual host configuration, and enable the new one you just created. Check that the new configuration is valid. If it looks OK, reload nginx.

$ sudo rm /etc/nginx/sites-enabled/default
$ sudo ln -s /etc/nginx/sites-available/your.domain.tld.conf /etc/nginx/sites-enabled/your.domain.tld.conf
$ sudo nginx -t
$ sudo systemctl reload nginx

In your browser, access http://your.domain.tld. Your browser window should be completely blank. If you inspect the HTTP response, 204 No Content is the correct code you're expecting to receive. You should not see the nginx welcome page, an HTTP error response code, or anything else.

TLS Configuration

Next, let's encrypt our non-response with a TLS certificate.

$ sudo certbot --nginx -d your.domain.tld

Certbot will ask you a few questions and, if all goes well, your new certificate will be added to /etc/nginx/sites-available/your.domain.tld.conf. The host config file should now look something like this:

server {
    server_name your.domain.tld;
    location / {
        return 204;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/your.domain.tld/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/your.domain.tld/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = your.domain.tld) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name your.domain.tld;
    listen 80;
    return 404; # managed by Certbot
}

Check that the new configuration is valid. If it looks OK, reload nginx.

$ sudo nginx -t
$ sudo systemctl reload nginx

In your browser, access https://your.domain.tld. The response should still be 204 No Content like before, but encrypted with TLS this time.