How To Secure Apache Server with Let’s Encrypt on Ubuntu

Let’s Encrypt is a Certificate Authority (CA) that encourages acquiring and introducing free TLS/SSL security, in this manner empowering scrambled HTTPS on the webserver. It streamlines the cycle by giving a product customer, Certbot, that endeavours to mechanize most (if not the entirety) of the necessary advances. As of now, the whole cycle of getting and installing an SSL/TLS is completely automated on Apache.

In this guide, we’ll use Certbot to get a free SSL certificate for Apache on Ubuntu 20.04 and ensure this certificate is set up to update automatically.

This instructional exercise uses a different virtual host rather than Apache’s default created a file for setting up the site that will be encrypted and secure by Let’s Encrypt SSL. We suggest making new Apache virtual host file for every host in a server since it assists with staying away from regular errors and keeps up the default virtual host as a fallback configuration.

Installing Certbot

To get an SSL certificate with Let’s Encrypt, we’ll first have to introduce the Certbot programming on your server. We’ll utilize the default Ubuntu bundle package for this. 

We need two modules: certbot, and python3-certbot-apache. The last is a module that configured Certbot with Apache, making it conceivable to mechanize acquiring a declaration and arranging HTTPS inside your web server with a simple one-line command.

$ sudo apt install certbot python3-certbot-apache

Creating a new Apache Virtual Host file

To have the option to consequently acquire and arrange SSL for your web server, Certbot needs to locate the right virtual host inside your Apache setup. Your server domain name will be recovered from the ServerName and ServerAlias mandates characterized inside your VirtualHost code block.

Apache on Ubuntu 20.04 has one server block active by default that is set up to serve the site from the /var/www/html dir. While this functions admirably for one site, it can become harder if you are serving more than one site. Rather than changing /var/www/html, how about we make a catalogue structure inside/var/www for a your_domain website, leaving /var/www/html set up as the default registry to be served if a customer demand doesn’t coordinate some other website.

Create the directory for your_domain as follows:

$ sudo mkdir /var/www/your_domain

Next, allot responsibility for dir with the $USER variable:

$ sudo chown -R $USER:$USER /var/www/your_domain

The permissions of your web roots should be correct if you haven’t modified your unmask value, which sets default file permissions. to make sure that your permissions are correct and permit the owner to read, write, and execute the files while granting only read and execute permissions to groups et al., you’ll input the subsequent command:

$ sudo chmod -R 755 /var/www/your_domain

Next, make an example index.html page utilizing nano or your favourite editor:

$ sudo nano /var/www/your_domain/index.html

Inside, add the accompanying example HTML:

<html>
    <head>
        <title>Your_domain!</title>
    </head>
    <body>
        <h1>Success!  your virtual host is working!</h1>
    </body>
</html>

Save and close the document when you are done.

In order for Apache to serve this content, it’s necessary to make a virtual host file with the right directives. rather than modifying the default configuration file located at /etc/apache2/sites-available/000-default.conf directly, let’s make a replacement one at /etc/apache2/sites-available/your_domain.conf:

$ sudo nano /etc/apache2/sites-available/your_domain.conf

Paste within the following configuration block, which is analogous to the default, but updated for our new directory and domain name:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName your_domain
    ServerAlias www.your_domain
    DocumentRoot /var/www/your_domain
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Notice that we’ve updated the DocumentRoot to our new directory and ServerAdmin to an email that the your_domain site administrator can access. We’ve also added two directives: ServerName, which establishes the bottom domain that ought to match for this virtual host definition, and ServerAlias, which defines further names that ought to match as if they were the bottom name.

Save and close the document when you are done.

Now, we need to enable the configuration with the a2ensite command:

$ sudo a2ensite your_domain.conf

Next, let’s check for new virtual host configuration faults:

If everything will be ok then you would receive the following output:

Output
Syntax OK

Restart Apache Server to perform your changes:

$ sudo systemctl restart apache2

With these changes, Certbot will have the option to locate the right VirtualHost area and update it.

Allowing HTTPS Port Through the Firewall

If you’ve got the UFW firewall enabled, you’ll have to adjust the settings to permit HTTPS traffic. Upon installation, Apache registers a couple of different UFW application profiles. we will leverage the Apache Full profile to permit both HTTP and HTTPS traffic on your server.

To check what sort of traffic is presently permitted on your server, you can use the following command:

$ sudo ufw status

If you’ve got followed one among our Apache installation guides, your output should look something like this, meaning that only HTTP traffic on port 80 is currently enabled:

Output
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Apache                     ALLOW       Anywhere             
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Apache (v6)                ALLOW       Anywhere (v6)

To also allow in HTTPS traffic, permit the “Apache Full” profile and erase the repetitive “Apache” profile:

$ sudo ufw allow 'Apache Full'
$ sudo ufw delete allow 'Apache'

Your status should look like this:

Output
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Apache Full                ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Apache Full (v6)           ALLOW       Anywhere (v6)

You are currently prepared to run Certbot and get your SSL.

Getting an SSL Certificate

Certbot provides a spread of the way to get SSL certificates through plugins. The Apache plugin will lookout of reconfiguring Apache and reloading the configuration whenever necessary. To use this plugin, type the following:

$ sudo certbot --apache

This script will prompt you to answer a series of questions so as to configure your SSL certificate. First, it’ll ask you for a legitimate e-mail address. This email is going to be used for renewal notifications and security notices:

Output
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): you@your_domain

After providing a legitimate e-mail address, hit ENTER to proceed to subsequent step. you’ll then be prompted to verify if you comply with Let’s Encrypt terms of service. you’ll confirm by pressing A then ENTER:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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

Next, you’ll be asked if you’d wish to share your email with the Electronic Frontier Foundation to receive news and other information. If you are doing not want to subscribe their content, type N. Otherwise, type Y. Then, hit ENTER to proceed to the subsequent step.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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

The next step will prompt you to tell Certbot of which domains you’d wish to activate HTTPS for. The listed domain names are automatically obtained from your Apache virtual host configuration, that’s why it’s important to form sure you’ve got the right ServerName and ServerAlias settings configured in your virtual host. If you’d wish to enable HTTPS for all listed domain names (recommended), you’ll leave the prompt blank and hit ENTER to proceed. Otherwise, select the domains you would like to enable HTTPS for by listing each appropriate number, separated by commas and/ or spaces, then hit ENTER.

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: your_domain
2: www.your_domain
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 

You’ll get output like follow:

Obtaining a new certificate
Performing the following challenges:
http-01 challenge for your_domain
http-01 challenge for www.your_domain
Enabled Apache rewrite module
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/apache2/sites-available/your_domain-le-ssl.conf
Enabled Apache socache_shmcb module
Enabled Apache ssl module
Deploying Certificate to VirtualHost /etc/apache2/sites-available/your_domain-le-ssl.conf
Enabling available site: /etc/apache2/sites-available/your_domain-le-ssl.conf
Deploying Certificate to VirtualHost /etc/apache2/sites-available/your_domain-le-ssl.conf

Next, you’ll be prompted to pick whether or not you would like HTTP traffic redirected to HTTPS. In practice, meaning when someone visits your website through unencrypted channels (HTTP), they’re going to be automatically redirected to the HTTPS address of your website. Choose 2 to enable the redirection, or 1 if you would like to stay both HTTP and HTTPS as separate methods of accessing your website.

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

After this step, Certbot’s configuration is finished, and you’ll be presented with the ultimate remarks about your new certificate, where to locate the generated files, and the way to check your configuration using an external tool that analyzes your certificate’s authenticity:

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

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

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/your_domain/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/your_domain/privkey.pem
   Your cert will expire on 2020-07-27. 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

Your certificate is now installed and loaded into Apache’s configuration. Try reloading your website using https:// and see your browser’s security indicator. It should mean that your site is correctly secured, typically by including a lock icon within the address bar.

Verifying Certbot Auto-Renewal

Let’s Encrypt’s certificates are only valid for ninety days. this is often to encourage users to automate their certificate renewal process, also on make sure that misused certificates or stolen keys will expire sooner instead of later.

The certbot package we installed takes care of renewals by including a renew script to /etc/cron.d, which is managed by a systemctl service called certbot.timer. This script runs twice each day and can automatically renew any certificate that’s within thirty days of expiration.

To check the status of this service and confirm it’s active and running, you’ll use:

$ sudo systemctl status certbot.timer

You’ll get output similar to follow:

Output
● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-04-28 17:57:48 UTC; 17h ago
    Trigger: Wed 2020-04-29 23:50:31 UTC; 12h left
   Triggers: ● certbot.service

Apr 28 17:57:48 fine-turtle systemd[1]: Started Run certbot twice daily.

To test the renewal process, you’ll do a dry run with certbot:

$ sudo certbot renew --dry-run

If you see no errors, you’re ready. When necessary, Certbot will renew your certificates and reload Apache to select up the changes. If the automated renewal process ever fails, Let’s Encrypt will send a message to the e-mail you specified, warning you when your certificate is close to expiring.