SSL Offloading and Let's Encrypt Certificate Integration

SSL offloading allows an application server to serve only the business functionalities by delegating the encryption/decryption to a dedicated web server running as a reverse proxy.

Securing web communications with SSL/TLS certificates is crucial for protecting sensitive data. But depending on the inbound traffic volume, you can delegate the encryption-decryption task to a dedicated web server allowing your application server to focus on serving the business functionality only.

Let’s Encrypt, a free and open certificate authority, provides an accessible way to obtain and manage SSL certificates. This blog post will explore leveraging Let’s Encrypt certificates for SSL offloading using the Apache HTTP Server as a reverse proxy on an Ubuntu 22.10 machine.

Prerequisites

Before proceeding, ensure that you have the following:

  1. A domain name or subdomain pointing to your server’s IP address.
  2. Administrative access to your server or root privileges.
  3. An application (say, a springboot application) running on port 8080. Please note that we must update the following steps based on the port number.

Setup

Install Apache HTTP server: Execute the following commands to install the Apache webserver that will act as a reverse proxy for our backend application.

# install apache
sudo apt install apache2
# check status
sudo systemctl status apache2

Install Certbot: Start by installing Certbot, a widely used Let’s Encrypt client that simplifies the certificate management process. You can follow the official documentation specific to your operating system for installation instructions.

sudo apt update
sudo apt install certbot
sudo apt install python3-certbot-apache

Configure Apache mods: To enable the Apache HTTP Server as a reverse proxy, ensure the required modules are enabled. Run the following commands:

sudo a2enmod ssl
sudo a2enmod proxy
sudo a2enmod proxy_balancer
sudo a2enmod proxy_http

# restart apache
sudo systemctl restart apache2

Obtain Let’s Encrypt Certificates: Use Certbot to obtain SSL certificates for your domain or subdomain. Run the following command:

sudo certbot certonly --apache -d your-domain.com

# follow on-screen prompts. the final cert confirmation should be similar
# to the one mentioned below

Requesting a certificate for your-domain.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your-domain.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/your-domain.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.

Replace your-domain.com with your existing domain or subdomain. Certbot will guide you through the process, and upon successful completion, the certificates will be stored in the /etc/letsencrypt/live/your-domain.com/ directory.

Configure Apache as a Reverse Proxy with SSL Offloading: Next, configure Apache as a reverse proxy with SSL offloading. Open the Apache configuration file, usually located at /etc/apache2/sites-available/000-default.conf, and add the following lines within the appropriate VirtualHost block:

<VirtualHost *:80>
    ServerName your-domain.com
    Redirect permanent / https://your-domain.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName your-domain.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/your-domain.com/chain.pem

    # Proxy settings
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
</VirtualHost>

Ensure you replace “your-domain.com” with your actual domain or subdomain and configure the appropriate ProxyPass and ProxyPassReverse directives to point to your backend server or application.

Configure Apache as a Reverse Proxy with SSL Offloading for multiple domains: While the above mentioned option works, it may soon become a challenge if we are trying to add multiple site configurations in the default /etc/apache2/sites-available/000-default.conf file.

In order to keep the setup clean, a better option is to create a seperate configuration file for each site in a seperate file and enable those individual configurations. Let’s start by creating a new file /etc/apache2/sites-available/your-domain.com.conf

<VirtualHost *:80>
    RequestHeader set X-Forwarded-Proto "http"
    ServerName your-domain.com
    Redirect permanent / https://your-domain.com/
</VirtualHost>

<VirtualHost *:443>
    RequestHeader set X-Forwarded-Proto "https"
    ServerName your-domain.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/your-domain.com/chain.pem

    # Proxy settings
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
</VirtualHost>

Once created, run the a2ensite command to enable the newly added site configuration: sudo a2ensite your-domain.com.conf. Following this pattern, you can add as many sites required and enable those accordingly.

Restart Apache: Do not forget to restart Apache using the appropriate command for your system for the changes to take effect:

sudo systemctl restart apache2

Automate Certificate Renewal

As mentioned above, the Certbot will set up a background task to renew certificates. You can check the job via the systemctl list-timers command.

One can also set up a custom job to regularly check the certificates and avoid downtime. To automate their renewal, set up a cron job to run the renew command: certbot renew

sudo crontab -e
30 2 * * 1 certbot renew >> /var/log/le-renew.log

This will create a new cron job that will execute the letsencrypt-auto renew command every Monday at 0230hrs.


That is all for this post. If you want to share any feedback, please drop me an email, or contact me on any social platforms. I’ll try to respond at the earliest. Also, please consider subscribing feed for regular updates.

Be notified of new posts. Subscribe to the RSS feed.