Setting up Server Blocks and Certificates in Nginx

One of the useful features of HTTP is that the Host: portion of the HTTP header is passed to the HTTP server (e.g., nginx) when the user visits the website. This means that if you have multiple domain names pointed at the same server, you can know which domain name a user is using to visit the page. If you know that, you can actually serve different web pages to different domain names. In this activity, we'll set that up using Nginx server blocks. Once we have those set up, we can use Certbot and LetsEncrypt to encrypt our connection to the website.

Prerequisites

  • A working server running Ubuntu, with nginx installed
  • Two different DNS records (domain names) that point to your server. In our examples, I'll use site1.example.com and site2.example.com. You'll have to substitute in your own domain names
  • Some basic Linux command line skills

Steps

Setting up the websites

First we need to create two different websites that can be served by Nginx, our web server.

  1. Create two new folders in the /var/www/ directory on the computer. I'll use /var/www/site1/html and /var/www/site2/html for my examples. Those folders need to be globally readable (by all users).
  2. Add an index.html file to each of the folders. Make sure that the contents of the index.html are different from each other so you can tell if you're visiting the two different pages.

Telling Nginx about our sites

Now that we've created the pages, we need to tell Nginx that they exist, and which one maps to which domain name. We do this by creating new server configuration files called server blocks. In those server blocks, we tell Nginx what domain name to expect, and where the root of the website is for that domain name. An Nginx server can have as many server blocks as you want to create, as long as the server can handle the connections from users.

  1. Create a new file for your first site at the following location: /etc/nginx/sites-available/site1.example.com (substitute your own domain name in the file name)
  2. In that file, put the following content, making sure to substitute in your file path and domain name:
server {
    listen 80;
    server_name site1.example.com;

    root /var/www/site1/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
  1. Create another new file for your second site: /etc/nginx/sites-available/site2.example.com
  2. In that file, put the following content, making sure to substitute in the file path and domain name for your second site:
server {
    listen 80;
    server_name site2.example.com;

    root /var/www/site2/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
  1. Run the following commands to create a virtual copy of the file in the sites-enabled folder, which enables them for Nginx:
sudo ln -s /etc/nginx/sites-available/site1.example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site2.example.com /etc/nginx/sites-enabled/
  1. Now you can check the nginx configuration with sudo nginx -t. If that tells you that the configuration file syntax is okay and the configuration test is successful, then you're good to reboot nginx. If it tells you otherwise, then you have errors in your configuration files you need to figure out.
  2. Reboot nginx with sudo systemctl restart nginx

Once Nginx is restarted, you should now be able to visit two different websites by going to site1.example.com and site2.example.com.

Securing your website

Now that you have the site enabled, with DNS pointing to your server and Nginx set up to recognize your domains, it's time to finally secure your website. Thankfully, we can get free security certificates for any website we run through a service called LetsEncrypt

  1. Install LetsEncrypt's automatic certificate manager tool, certbot:
sudo snap install --classic certbot
  1. Run certbot with the --nginx flag to tell it to update your nginx configuration
sudo certbot --nginx
  1. You'll need to provide an email address and agree to the LetsEncrypt terms of service. Once that's complete, you'll have working HTTPS certificates on your website
  2. If your server is on AWS, now that you have HTTPS, you may need to make sure to add the security group rule to allow HTTPS traffic onto your website (TCP port 443). Without access to port 443, HTTPS won't work.