Step 8: Install an SSL Certificate

Domain Names

Using a domain name gives you access to free SSL technology that is easy to use. Otherwise, you’ll have to use a self-signed certificate if you want to use SSL to protect web traffic on your box. You can also create sub-domain names for your projects and web apps.

There are many domain name registrars. We recommend purchasing one so you don’t lose access to it. However, you can use a free one for temporary use or for testing.

Freenom

Freenom.com is a source for free domains names from TLDs .tk, .ml, ga, .cf, and .gq.

  1. Navigate to Freenom.com.

  2. Search for a domain name, select it, then checkout

  3. Select the number of free months that you want (1-12)

  4. Click Use DNS and enter the IP address of your VPS

  5. Verify your email address and then fill in your account information

../../_images/freenom3.png

Add an SSL Cert to your domain name

  1. Log into your domain name registrar and point the root domain name (example.com) and the www subdomain name (www.domain.com) to the IP address of your VPS

    • Wait 2-3 minutes for the changes to take affect.

    • Don’t try immediately.

  2. Ping the domain name from a terminal (MobaXterm or Window’s CMD) to verify if it is active. Sometimes, it takes many hours for DNS entries to update.

    C:\Users\user>ping example.com
    
    Pinging example.com [46.105.29.128] with 32 bytes of data:
    Reply from 46.105.29.128: bytes=32 time=133ms TTL=48
    Reply from 46.105.29.128: bytes=32 time=137ms TTL=48
    Reply from 46.105.29.128: bytes=32 time=134ms TTL=48
    Reply from 46.105.29.128: bytes=32 time=134ms TTL=48
    
    Ping statistics for 46.105.29.128:
        Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
    Approximate round trip times in milli-seconds:
        Minimum = 133ms, Maximum = 137ms, Average = 134ms
    
    C:\Users\user>
    
  3. Now, we need to create the directory for the web files and the Nginx virtual host for our domain name

    • We should verify the config after we modify to detect errors.

  4. First, we need to create a directory for the web files and create a basic HTML page.

    mkdir -p

    Creates the directory structure.

    Flag -p

    Informs the system to create the deep directories (html) if the shallow ones do not exist (example.com).

    chown -R

    Changes the directory owner from root to www-data. This is important for (1) security and (2) Nginx might not be able to access the files if they are owned by root.

    sudo mkdir -p /var/www/example.com/html
    sudo chown -R www-data:www-data /var/www/example.com/html
    sudo nano /var/www/example.com/html/index.html
    
  5. Add some simple HTML to the index.html file.

    index.html
    <html>
        <head>
            <title>Welcome!</title>
        </head>
        <body>
            <h1>Hello world!</h1>
        </body>
    </html>
    
  6. Create the Nginx vhost file for the base domain and the www subdomain

    • The server_name directive in the Nginx site should have references to both, which identifies example.com and www.exmple.com as the same.

    • server_name example.com www.example.com;

    sudo nano /etc/nginx/sites-available/example.com
    
    /etc/nginx/sites-available/example.com
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    server {
        listen 80;
        listen [::]:80;
    
        root /var/www/example.com/html;
        index index.html index.htm index.nginx-debian.html index.php;
    
        server_name example.com www.example.com;
    
        location / {
                try_files $uri $uri/ =404;
        }
    
        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }
    }
    
  7. Verify the config using nginx -t

    • We should verify the config after we modify to detect errors.

    • If we don’t, then Nginx will not restart.

    sudo nginx -t
    
  8. Next, we need to enable the config, which tells Nginx to load the configuration file

    • To do, so, we’ll use the ln command to create a symbolic link from the file to the directory that contains all of the active configs

    sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
    
    1
    2
    3
    4
    5
    6
    root@vps298933:~# sudo nano /etc/nginx/sites-available/example.com
    root@vps298933:~# sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    root@vps298933:~#
    root@vps298933:~# sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
    
  9. Then, verify the link by viewing the contents of the /etc/nginx/sites-enabled/

    • ls lists the files and folders in the specified directory.

    • Flag -lh provides the files in a detailed list with human-readable file sizes.

    • You can use whichever format you find easiest to read.

    ls -lh /etc/nginx/sites-enabled/
    
    1
    2
    3
    root@vps298933:~# ls -lh /etc/nginx/sites-enabled/
    total 0
    lrwxrwxrwx 1 root root 44 Mar 14 23:13 example.com -> /etc/nginx/sites-available/example.com
    
  10. Next, restart Nginx and verify it is running

    • sudo systemctl restart nginx

    • sudo systemctl status nginx

  11. Test your web page

    • Using curl: curl example.com

    • Using your web browser: http://example.com

    • If it works, you should see your hello world page. Now, you are ready to install an SSL cert!

  12. Install Certbot to create SSL certs using Let’s Encrypt

    • certbot does not reside in the standard Ubuntu registry.

      • It is a third-party app the latest version (Electronic Frontier Foundation).

      • As a result, we have to manually add the certbot repository to apt.

    • We have to run apt update after we add the registry to the package will become available to apt

    sudo add-apt-repository ppa:certbot/certbot
    sudo apt update
    sudo apt -y install python-certbot-nginx
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    root@vps298933:~# sudo add-apt-repository ppa:certbot/certbot
    This is the PPA for packages prepared by Debian Let’s Encrypt Team and backported for Ubuntu(s).
    More info: https://launchpad.net/~certbot/+archive/ubuntu/certbot
    Press [ENTER] to continue or Ctrl-c to cancel adding it.
    
    Get:1 http://ppa.launchpad.net/certbot/certbot/ubuntu bionic InRelease [21.3 kB]
    Hit:2 http://nova.clouds.archive.ubuntu.com/ubuntu bionic InRelease
    Get:3 http://nova.clouds.archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
    Hit:4 http://ppa.launchpad.net/ondrej/php/ubuntu bionic InRelease
    Get:5 http://security.ubuntu.com/ubuntu bionic-security InRelease [83.2 kB]
    Get:6 http://nova.clouds.archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
    Get:7 http://ppa.launchpad.net/certbot/certbot/ubuntu bionic/main amd64 Packages [8,016 B]
    Get:8 http://ppa.launchpad.net/certbot/certbot/ubuntu bionic/main Translation-en [4,200 B]
    Fetched 280 kB in 1s (404 kB/s)
    Reading package lists... Done
    root@vps298933:~#
    root@vps298933:~# sudo apt -y install python-certbot-nginx
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    The following additional packages will be installed:
    certbot python3-acme python3-certbot python3-certbot-nginx python3-configargparse python3-future python3-icu python3-josepy
    python3-mock python3-ndg-httpsclient python3-parsedatetime python3-pbr python3-pyparsing python3-requests-toolbelt python3-rfc3339
    python3-tz python3-zope.component python3-zope.event python3-zope.hookable
    Suggested packages:
    python3-certbot-apache python-certbot-doc python-acme-doc python-certbot-nginx-doc python-future-doc python-mock-doc
    python-pyparsing-doc
    The following NEW packages will be installed:
    certbot python-certbot-nginx python3-acme python3-certbot python3-certbot-nginx python3-configargparse python3-future python3-icu
    python3-josepy python3-mock python3-ndg-httpsclient python3-parsedatetime python3-pbr python3-pyparsing python3-requests-toolbelt
    python3-rfc3339 python3-tz python3-zope.component python3-zope.event python3-zope.hookable
    0 upgraded, 20 newly installed, 0 to remove and 14 not upgraded.
    Need to get 1,213 kB of archives.
    After this operation, 6,406 kB of additional disk space will be used.
    Get:1 http://ppa.launchpad.net/certbot/certbot/ubuntu bionic/main amd64 python3-josepy all 1.1.0-2+ubuntu18.04.1+certbot+1 [27.8 kB]
    Get:2 http://nova.clouds.archive.ubuntu.com/ubuntu bionic/main amd64 python3-pbr all 3.1.1-3ubuntu3 [53.8 kB]
    .
    .
    .
    
  13. Now, we can use Certbot to encrypt HTTP traffic on our domain name and the www subdomain name.

    • After running the command:

      • Press A to accept the agreement

      • Press 2 at the end to redirect all traffic

    sudo certbot --register-unsafely-without-email --nginx -d example.com -d www.example.com
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    root@vps298933:~# sudo certbot --register-unsafely-without-email --nginx -d example.com
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator nginx, Installer nginx
    Registering without email!
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    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-v02.api.letsencrypt.org/directory
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (A)gree/(C)ancel: A
    Obtaining a new certificate
    Performing the following challenges:
    http-01 challenge for example.com
    Waiting for verification...
    Cleaning up challenges
    Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/example.com
    
    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/example.com
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Congratulations! You have successfully enabled https://example.com
    
    You should test your configuration at:
    https://www.ssllabs.com/ssltest/analyze.html?d=example.com
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    IMPORTANT NOTES:
    - Congratulations! Your certificate and chain have been saved at:
    /etc/letsencrypt/live/example.com/fullchain.pem
    Your key file has been saved at:
    /etc/letsencrypt/live/example.com/privkey.pem
    Your cert will expire on 2019-04-20. 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"
    - Your account credentials have been saved in your Certbot
    configuration directory at /etc/letsencrypt. You should make a
    secure backup of this folder now. This configuration directory will
    also contain certificates and private keys obtained by Certbot so
    making regular backups of this folder is ideal.
    - 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
    
    root@vps298933:~#
    
  14. Finally, refresh your page by pressing Ctrl+F5. You should see your new cert.

Video Walkthrough

Are you stuck? Use this recording to help you.

Watch on asciinema.org if the video will not load.