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
andsite2.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.
- 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). - Add an
index.html
file to each of the folders. Make sure that the contents of theindex.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.
- 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) - 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;
}
}
- Create another new file for your second site:
/etc/nginx/sites-available/site2.example.com
- 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;
}
}
- 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/
- 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. - 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
- Install LetsEncrypt's automatic certificate manager tool, certbot:
sudo snap install --classic certbot
- Run certbot with the
--nginx
flag to tell it to update your nginx configuration
sudo certbot --nginx
- 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
- 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.