How to get a free Let's Encrypt SSL via CertBot on Apache

An SSL (Secure Sockets Layer) certificate is a digital certificate that enables the establishment of a secure encrypted connection between a web server and a web browser. It ensures that the transmitted data remains private and cannot be intercepted or tampered with by unauthorized malicious parties.

An SSL certificate enables the use of the HTTPS protocol. The protocol makes the established connection secure, protects sensitive information, and verifies the identity of the website owner.

SSL certificates use asymmetric encryption - the server generates a public-private key pair, where the public key is included in the SSL certificate, and the private key remains stored on the server. When a browser connects to a website with an installed SSL certificate, it establishes a secure connection with the server with the public key. The data transmitted between is encrypted using the public key in the browser. It can only be decrypted using the private key, which is associated with it.

Certificate authorities are entities that cryptographically sign SSL certificates. This way they vouch for the authenticity of the protocol. Browsers have a list of trusted authorities, which they use to verify SSL certificates.

Let's Encrypt is a nonprofit certificate authority that provides free SSL/TLS certificates. Their mission is to make HTTPS encryption more accessible and widespread on the internet.

Certbot is a free software tool that simplifies the process of obtaining and managing a Let's Encrypt certificate.

In this tutorial, we will guide you through the steps of installing and utilizing CertBot on an Ubuntu 22.04 VPS with an Apache web server from AlphaVPS.

For a more detailed explanation of an Apache web server installation, you can refer to our guide here.


How to install CertBot

The installation process is quite straightforward.

First, we need to update our system.

sudo apt update

After that, we need to install the certbot package and the python3-certbot-apache, which integrates Certbot with the Apache webserver.

sudo apt install certbot python3-certbot-apache

We are able to confirm Certbot's installation by running systemctl status certbot

○ certbot.service - Certbot
     Loaded: loaded (/lib/systemd/system/certbot.service; static)
     Active: inactive (dead)
TriggeredBy: ● certbot.timer
       Docs: file:///usr/share/doc/python-certbot-doc/html/index.html
             https://certbot.eff.org/docs

Setting up a Virtual Host

Certbot automatically obtains and configures SSL by finding the correct virtual host within our Apache configuration files.

In our LAMP stack tutorial here, we provided a more detailed explanation of installing Apache and setting up a virtual host.

A virtual host can be created following these steps:

  1. Create a new directory for your virtual host's web content. This is usually located in the /var/www/ directory and should be named after your domain name.
sudo mkdir /var/www/"domain_name"

2. Create a new virtual host configuration file. This file is usually located in the /etc/apache2/sites-available/ directory and should be named after your domain name.

sudo nano /etc/apache2/sites-available/"domain_name".conf

3.  In the virtual host configuration file, specify the server name and server alias(es) for your virtual host, along with the document root directory.

You will need  to assign ownership of the document root directory with the $USER environment variable.

sudo chown -R www-data:www-data /var/www/"domain_name"

A sample configuration looks like this:

<VirtualHost *:80>
    ServerName "domain_name"
    ServerAlias "www.domain_name"
    DocumentRoot /var/www/"domain_name"
    ErrorLog ${APACHE_LOG_DIR}/"domain-name"-error.log
    CustomLog ${APACHE_LOG_DIR}/"domain-name"-access.log combined
</VirtualHost>

Make sure that  ServerName and ServerAlias  are correctly set.
The CertBot script relies on these. They are automatically obtained from our Apache virtual host configuration, so it’s important to make sure you have the correct ServerName and ServerAlias settings configured in the virtual host.

Save and close the file.

4. Enable the virtual host and reload Apache.

sudo a2ensite "domain-name"
sudo systemctl reload apache2

5. Add content to your web root directory.

Create a new HTML file, an index.html, and add some content like this HTML boilerplate.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML</title>
  </head>
  <body>
	<h1>Greetings from AlphaVPS</h1>
  </body>
</html>

Save and close the file.


Obtaining an SSL certificate

To automatically obtain an SSL certificate, we can use the Apache-Certbot plugin, that we installed earlier in this tutorial.

Simply run:

sudo certbot --apache

The script will guide us through multiple steps.

  1. Provide an active e-mail.
    It will be used for renewal notifications.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel):

Hit Enter to proceed to the next step.

2. Confirm the Terms of Service.

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?

Type Y and hit enter.

3. Subscribe to Electronic Frontier Foundation for news.

Would you be willing, once your first certificate is successfully issued, 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:

If you wish to receive news and other information on your e-mail, hit Y and Enter.
Otherwise, you can decline this by hitting N and Enter.

4. Select Domains

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

The listed domains are automatically obtained from your Apache virtual host configuration.

If you want to directly enable HTTPS for all listed domains, you can just press ENTER to proceed. Alternatively, select the number of the required domain and your certificate request will start. Once ready, you will receive the following output.

Requesting a certificate for domain-name.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/domain-name.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/domain-name.com/privkey.pem
This certificate expires on 2023-08-28.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for domain-name.com to /etc/apache2/sites-available/domain-name.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://domain-name.com

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

To confirm that everything works as intended, open your browser and access your website via the HTTPS protocol - https://domain-name.com .
If the lock icon before your domain is visualized as locked, this indicates that your site is secure with an active SSL certificate.


Renewing an SSL certificate

As you may have noticed in the previous step, after our certificate was received, we were also informed about its expiration date. Let's Encrypt certificates only last 90 days. This is done to ensure that misused certificates will expire as soon as possible.

The certbot package includes a script to /etc/cron.d that automatically renews our certificates.  It runs twice a day and will automatically renew any certificate that’s within thirty days of expiration.

The script is managed by a service - certbot.timer. We can confirm its status by running the following command:

sudo systemctl status certbot.timer

We will receive a similar output:

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset:>
     Active: active (waiting) since Tue 2023-05-30 08:14:50 UTC; 23h ago
    Trigger: Wed 2023-05-31 17:53:10 UTC; 10h left
   Triggers: ● certbot.service

We are also able to simulate and test the renewal process by running.
This way we will be entirely sure that everything is fine with our configuration and our certificate will be renewed.

sudo certbot renew --dry-run

You will receive a confirmation such as:

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/domain-name.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for domain-name.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/domain-name.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -