Objectives

This is Part 5 of a series called Hello, World: Blog.

We have a site, but we can only access it in the browser by IP address. As you’ve probably noticed, most websites have an address, also known as a URL or domain. The Domain Name System (DNS) forwards requests to the appropriate IP address based on its domain. For example, “brittanymoore.net” is my site’s domain, and it is linked to my Ubuntu server’s IP address.

In this post, you’ll:

  • Add a domain to your site using DNS records.
  • Set up an SSL certificate to enable HTTPS.

Prerequisites

Get a Domain Name

To acquire a domain name, you need to go through a registrar company. Like web hosts, there are many registrars to choose from, and you can pick whichever one you want. Domain names can often be transferred between registrars in the future, so don’t feel locked in to your current choice. Domain names typically cost a few dollars a year.

It’s up to you to select a registrar and a domain name for your blog - check out this article as a starting point.

Set up DNS

Note: This section provides some general information on DNS records, but the exact instructions on how to manage them will vary across different web hosts. The links provided are specific to DigitalOcean - if you use a different host provider, please check their documentation as well.

Once you have a registered domain, you’ll need to create DNS records for that domain on your web host. A DNS record is essentially a domain mapping that conveys how requests to that domain should be handled. For a basic blog, we’ll focus on two “types” of DNS record:

  • A (“address”) - link a domain directly to an IP
  • NS (“name server”) - indicate which name server a domain uses

The A records are fairly straightforward. If my domain is brittanymoore.net and my IP is 99.99.999.99, my A records might look like this:

Type | Hostname -------------| Value -----------------
A    | brittanymoore.net     | directs to 99.99.999.99
A    | www.brittanymoore.net | directs to 99.99.999.99

NS records are dependent on your web host. With DigitalOcean, I also need three NS records (one for each of their name servers). If you’re using a different web host, you’ll need to check their documentation for instructions regarding NS records.

Type | Hostname ---------| Value -------------------------
NS   | brittanymoore.net | directs to ns1.digitalocean.com
NS   | brittanymoore.net | directs to ns2.digitalocean.com
NS   | brittanymoore.net | directs to ns3.digitalocean.com

If your web host requires NS records, you’ll also need to configure your domain to use those name servers. You’ll do this through the registrar site, not your web host.

Set up HTTPS

At this point, our site is only accessible using the HTTP protocol. If you attempt to use HTTPS (i.e “https://brittanymoore.net”), it will refuse to connect. HTTPS is preferred whenever possible, because it is encrypted, but it requires a little extra setup.

In order to use HTTPS on our blog, we need to acquire and maintain an SSL (Secure Sockets Layer) certificate. SSL is the protocol used to encrypt our site communications.

To complete these steps, you’ll need the following:

  • A registered domain name
  • A-type DNS records on your web host linking the server IP to your domain name (see previous section)

Nginx Configuration

First, we need to update the Nginx default config file with the domain we are requesting a certificate for.

bannmoore@blog:~$ sudo nano /etc/nginx/sites-available/default

Scroll down until you see this line:

server_name _;

We’re going to replace that _ with our domain name and the www version of our domain name.

server_name brittanymoore.net www.brittanymoore.net;

Exit Nano (CTRL-X, Y, ENTER). Verify that the configuration changes are valid.

bannmoore@blog:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If you don’t see this output, then your file may have gotten malformed. Double-check your changes. If it’s all good, reload Nginx.

bannmoore@blog:~$ sudo systemctl reload nginx

Firewall Configuration

Check the current status of your firewall using sudo ufw. If your firewall is inactive, see the security post for instructions on how to set it up.

bannmoore@blog:~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Nginx HTTP                 ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Nginx HTTP (v6)            ALLOW       Anywhere (v6) 

If your output looks like this, then your site is currently configured to only allow HTTP traffic. Remember from the previous post that we can use ufw app list to see which profiles are available.

bannmoore@blog:~$ sudo ufw app list
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH

Let’s switch to the Nginx Full profile, which allows both HTTP and HTTPS. This is necessary for the next step. Make sure you delete the old profile so that only one Nginx profile is active.

bannmoore@blog:~$ sudo ufw allow 'Nginx Full'
Rule added
Rule added (v6)
bannmoore@blog:~$ sudo ufw delete allow 'Nginx HTTP'
Rule deleted
Rule deleted (v6)

Install Certbot

Now we’re going to install a package called Certbot, that will help us enable and automatically maintain our SSL certificate. To ensure we get the most up-to-date version, we’re going to add the Ubuntu software repository for Certbot and then install it from there. When prompted, press ENTER to continue the installation.

bannmoore@blog:~$ sudo add-apt-repository ppa:certbot/certbot

Now we can install Certbot’s Nginx package.

bannmoore@blog:~$ sudo apt-get update
bannmoore@blog:~$ sudo apt-get install python-certbot-nginx

Obtain an SSL Certificate

To set up our site’s certificate, we’re going to run Certbot with the --nginx plugin. Replace the URLs below with your domain; these should be the same values you entered in the Nginx configuration earlier in this post.

bannmoore@blog:~$ sudo certbot --nginx -d brittanymoore.net -d www.brittanymoore.net

If this is your first time running Certbot on the server (and it probably is), it’ll add a few prompts.

  1. Enter an email address
  2. Agree to the terms of service
  3. Agree or Decline sharing your email address with Electronic Frontier
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): moore.brittanyann@gmail.com
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
-------------------------------------------------------------------------------
(Y)es/(N)o: N

Once that’s all done, it’ll try to get a new certificate.

Obtaining a new certificate
Performing the following challenges:
http-01 challenge for brittanymoore.net
http-01 challenge for www.brittanymoore.net
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default

Then it’ll prompt you to select a redirection strategy. 1 leaves the configuration as-is, with both HTTP and HTTPS enabled. 2 will redirect all requests to HTTPS. I recommend choosing 2 unless you have a pressing need to HTTP requests to work. You can revert that setting later on if needed.

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/default
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/default

Finally, you should see a success message indicating that HTTPS is enabled.

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://brittanymoore.net and
https://www.brittanymoore.net

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=brittanymoore.net
https://www.ssllabs.com/ssltest/analyze.html?d=www.brittanymoore.net
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/brittanymoore.net/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/brittanymoore.net/privkey.pem
   Your cert will expire on 2018-09-30. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

You can test the changes in the browser by attempting to access your site through the https:// urls. If you selected option 2 above, then the non-HTTP urls should also redirect to HTTPS.

Certificate Renewal

Certbot uses Let’s Encrypt to get certificates, which are only valid for 90 days. To avoid the pain of manually renewing your certificate, Certbot should automatically renew for you. You can validate the renewal with --dry-run.

bannmoore@blog:~$ sudo certbot renew --dry-run

This will simulate the certificate renewal without actually doing it. If it completes without any errors, then Certbot is working as expected.

Summary

In this post, you set up your website with DNS and HTTPS. Congratulations! You’ve completed the Hello, World: Blog tutorial.