How To Secure Apache with mod_md Let’s Encrypt on Ubuntu 20.04 LTS

BaoMinh

Moderator
Aug 13, 2013
592
6
18
apachelogo.gif

How do I secure Apache with mod_md Let’s Encrypt on Ubuntu 20.04 and obtain a free TLS/SSL certificate? How do I secure Apache 2 with Let’s Encrypt on Ubuntu 20.04 LTS server?

Apache server comes with a module named mod_md. We can use this for certificate provisioning via the ACME protocol. This page explains how to install, set up and configure Apache with a mod_md module to secure traffic with Let’s Encrypt free TLS/SSL certificate on Ubuntu 20.04 LTS server.

How to Secure Apache with mod_md Let’s Encrypt on Ubuntu 20.04


Let’s Encrypt is a CA that follows the ACME protocol. One can use Let’s Encrypt to issue free TLS/SSL certificates for Apache, Nginx, and other servers. In this tutorial, you will use mod_md to obtain a free TLS/SSL certificate for Apache 2 on Ubuntu 20.4 and set up your certificate to renew automatically too. Our sample set up is as follows:

  • Domain – www42.cyberciti.biz
  • HTTPS port – 443
  • Virtual domain config file – /etc/apache2/sites-available/www42.cyberciti.biz.conf

Make sure Apache installed by following How to install Apache on Ubuntu 20.04 guide.

Step 1 – Installing mod_md for Let’s Encrypt


First, apply updates using the apt command:
sudo apt update
sudo apt upgrade
Then, install the mod_md by typing the following command:
sudo apt install libapache2-mod-md
Install Apache with mod_md Let's Encrypt on Ubuntu Linux 20.04 LTS


Enabling mod_md on Ubuntu 20.04 LTS


Turn on mod_md, type:
sudo a2enmod md
Sample outputs:


Enabling module md.
To activate the new configuration, you need to run:
systemctl restart apache2


Make sure you activate the mod_ssl too, run:
sudo a2enmod ssl
Outputs:



Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
systemctl restart apache2

Considering dependency setenvif for ssl: Module setenvif already enabled Considering dependency mime for ssl: Module mime already enabled Considering dependency socache_shmcb for ssl: Enabling module socache_shmcb. Enabling module ssl. See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates. To activate the new configuration, you need to run: systemctl restart apache2


Apache 2 must be reloaded or restarted with the help of the systemctl command”
sudo systemctl reload apache2.service

Step 2 – Set up the SSL certificate


Make sure your Apache 2 is working and listens on port 80. Verify using the ss command or netstat command:
sudo netstat -tulpn | grep ':80'
## or ##
sudo ss -tulpn | grep ':80'
Sample outputs:


tcp LISTEN 0 128 *:80 *:* users:(("apache2",pid=2550,fd=4),("apache2",pid=2549,fd=4),("apache2",pid=2548,fd=4))


All clients must connect to your server over port 80. Otherwise, you will not get validated for Let’s Encrypt certificate. From your desktop, run:
curl -I http://www42.cyberciti.biz
curl command outputs validting that we can connect to the port TCP port 80:


HTTP/1.1 200 OK
Date: Wed, 06 May 2020 19:30:43 GMT
Server: Apache/2.4.41 (Ubuntu)
Last-Modified: Wed, 06 May 2020 19:15:29 GMT
ETag: "15e-5a4ff965902a3"
Accept-Ranges: bytes
Content-Length: 350
Vary: Accept-Encoding
Connection: close
Content-Type: text/html


Let us edit the /etc/apache2/sites-available/www42.cyberciti.biz.conf, enter:
sudo nano /etc/apache2/sites-available/www42.cyberciti.biz.conf
At the top of file add the following three mod_md directives:



## Secure Apache with mod_md Let's Encrypt directives ##
ServerAdmin [email protected]
MDCertificateAgreement accepted
MDomain www42.cyberciti.biz

## Secure Apache with mod_md Let's Encrypt directives ## ServerAdmin [email protected] MDCertificateAgreement accepted MDomain www42.cyberciti.biz


Where,

  • ServerAdmin [email protected] : mod_md will use this email address when registering your domains at Let’s Encrypt.
  • MDCertificateAgreement accepted : You must accept the Terms of Service conditions as set by Let’s Encrypt.
  • MDomain www42.cyberciti.biz : Declare a domain named that should be manged by mod_md to issue and renew certificates. You can use full domain name such as www.cyberciti.biz or cyberciti.biz or www42.cyberciti.biz. Make sure it matches to ServerName.

Here is my complete config file :



## Apache with mod_md Let's Encrypt ##
## mod_md config for Let's Encrypt ##
ServerAdmin [email protected]
MDCertificateAgreement accepted
MDomain www42.cyberciti.biz

## HTTP port 80 config ##
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName www42.cyberciti.biz
DocumentRoot /home/cyberciti.biz/html
DirectoryIndex index.html
ErrorLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-error.log
CustomLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-access.log combined
# Redirect all http requests to HTTPS (uncomment the following two lines when HTTPS issued)
# RewriteEngine On
# RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

## HTTPS Config ##
<VirtualHost *:443>
SSLEngine on
ServerAdmin [email protected]
ServerName www42.cyberciti.biz
DocumentRoot /home/cyberciti.biz/html
DirectoryIndex index.html
ErrorLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-ssl-error.log
CustomLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-ssl-access.log combined
# Turn on HTTP/2
Protocols h2 http/1.1
# Set HTTP Strict Transport Security
Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>
## Only enable TLS v1.3 and avoid older protocols ##
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLHonorCipherOrder off
SSLSessionTickets off

## Turn on OCSP Stapling ##
SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

## Permission for our DocumentRoot ##
<Directory /home/cyberciti.biz/html>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

## Apache with mod_md Let's Encrypt ## ## mod_md config for Let's Encrypt ## ServerAdmin [email protected] MDCertificateAgreement accepted MDomain www42.cyberciti.biz ## HTTP port 80 config ## <VirtualHost *:80> ServerAdmin [email protected] ServerName www42.cyberciti.biz DocumentRoot /home/cyberciti.biz/html DirectoryIndex index.html ErrorLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-error.log CustomLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-access.log combined # Redirect all http requests to HTTPS (uncomment the following two lines when HTTPS issued) # RewriteEngine On # RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] </VirtualHost> ## HTTPS Config ## <VirtualHost *:443> SSLEngine on ServerAdmin [email protected] ServerName www42.cyberciti.biz DocumentRoot /home/cyberciti.biz/html DirectoryIndex index.html ErrorLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-ssl-error.log CustomLog ${APACHE_LOG_DIR}/www42.cyberciti.biz-ssl-access.log combined # Turn on HTTP/2 Protocols h2 http/1.1 # Set HTTP Strict Transport Security Header always set Strict-Transport-Security "max-age=63072000" </VirtualHost> ## Only enable TLS v1.3 and avoid older protocols ## SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2 SSLHonorCipherOrder off SSLSessionTickets off ## Turn on OCSP Stapling ## SSLUseStapling On SSLStaplingCache "shmcb:logs/ssl_stapling(32768)" ## Permission for our DocumentRoot ## <Directory /home/cyberciti.biz/html> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>

Turn on Apache’s mod_rewrite and mod_headers under Ubuntu


We have already declared a rewrite rule in our config, so we need mod_rewrite. Hence, type the following command:
sudo a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
systemctl restart apache2
Turn on mod_headers too:
sudo a2enmod headers
Enabling module headers.
To activate the new configuration, you need to run:
systemctl restart apache2

Check for config errors, run:


sudo apache2ctl configtest
Syntax OK

Step 3 – Open HTTPS (TCP port 443) using the UFW firewall on Ubuntu


Run the following ufw command to open TCP port 443 for everyone:
sudo ufw allow 443/tcp comment 'accept secure Apache connections'
Verify it rules:
sudo ufw status
See “How To Configure Firewall with UFW on Ubuntu 20.04 LTS” for more info.

Step 4 – Obtaining an SSL certificate using mod_md


So far, we installed mod_md for Apache on Ubuntu, turned on all essential modules, and open required TCP ports using a firewall. It is time to restart our Apache 2 server to obtain the free TLS/SSL certificate using Let’s Encrypt certificate authority (CA). Therefore, restart the Apache 2 server:
sudo systemctl restart apache2.service
As soon as Apache 2 restarted mod_md will contact Let’s Encrypt and request a certificate for your domain. Typically it takes up to one minute. You can check the server error log or Apache’s mod_status page to see if the request was successful or not. Here is what you will see in erro.log file:
sudo tail -f /var/log/apache2/error.log
One can use the grep command too:
sudo grep 'The Managed Domain' /var/log/apache2/error.log
Sample outputs indicating that LE has issued us a free TLS/SSL certificate:


[Wed May 06 20:17:38.112849 2020] [md:notice] [pid 21777:tid 139807872861952] AH10059: The Managed Domain www42.cyberciti.biz has been setup and changes will be activated on next (graceful) server restart.


Of course we can visit server-status url too. For example:
Managed Domain Status for Apache with mod_md Let's Encrypt
Click to enlarge
A graceful Apache 2 server restart now is recommended to activate the certificate:
sudo systemctl reload apache2.service

Step 5 – Test secure Apache 2 connection


All you have to do is type the following command or use a web browser such as Firefox/Chrome to make sure you are getting HTTPS connection:
curl -I https://www42.cyberciti.biz
mod_md status
curl command in action verify that our HTTPS connection is working and traffic is secured and encrypted
Here is outputs from SSL Lab’s test:
How To Secure Apache with Let's Encrypt on Ubuntu 20.04 LTS
My secure Apache server with Let’s Encrypt TLS/SSL running on Ubuntu 20.04 LTS and verified by SSL Lab’s test

Step 6 – Automatically renewing an SSL certificate using mod_md and watchdog_module


The mod_md uses mod_watchdog module, which provides programmatic hooks for other modules to run tasks such as renewing TLS/SSL certificates and more periodically. In other words, auto-renew mode requires mod_watchdog to be active in your server. Hence, verify that mod_watchdog is activated using the following command:
sudo apache2ctl -M
sudo apache2ctl -M | grep mod_watchdog
Loaded Modules:


core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
....
..
...
ssl_module (shared)
status_module (shared)

Step 7 – Monitoring certificate status


Now we set up Apache with mod_md and got a free TLS/SSL from Let’s Encrypt. It is time to monitor status of our certificate. There are two ways. First open /server-status URL:
Managed Domains Apache Status
Click to enlarge
Edit your server config file, run:
sudo nano /etc/apache2/sites-available/www42.cyberciti.biz.conf
Append the following:



<Location "/md-status">
SetHandler md-status
</Location>

<Location "/md-status"> SetHandler md-status </Location>


Save and close the file. Restart the server and run:
sudo systemctl restart apache2.service
curl https://www42.cyberciti.biz/md-status
Sample outputs:



{
"version": "2.0.10",
"managed-domains": [
{
"name": "www42.cyberciti.biz",
"domains": [
"www42.cyberciti.biz",
"www43.cyberciti.biz"
],
"contacts": [
"mailto:[email protected]"
],
"transitive": 1,
"ca": {
"proto": "ACME",
"url": "https://acme-v02.api.letsencrypt.org/directory",
"agreement": "accepted"
},
"state": 2,
"renew-mode": 1,
"renew-window": "33%",
"warn-window": "10%",
"must-staple": false,
"cert": {
"valid-from": "Wed, 06 May 2020 19:17:37 GMT",
"valid-until": "Tue, 04 Aug 2020 19:17:37 GMT",
"serial": "040E339A0A7D2224819A550BBB4596279F67",
"sha256-fingerprint": "d78933fa946cb71810111876049defa4feb6820c319c69918ba925b463bbd11c"
},
"renew": false
}
]
}

{ "version": "2.0.10", "managed-domains": [ { "name": "www42.cyberciti.biz", "domains": [ "www42.cyberciti.biz", "www43.cyberciti.biz" ], "contacts": [ "mailto:[email protected]" ], "transitive": 1, "ca": { "proto": "ACME", "url": "https://acme-v02.api.letsencrypt.org/directory", "agreement": "accepted" }, "state": 2, "renew-mode": 1, "renew-window": "33%", "warn-window": "10%", "must-staple": false, "cert": { "valid-from": "Wed, 06 May 2020 19:17:37 GMT", "valid-until": "Tue, 04 Aug 2020 19:17:37 GMT", "serial": "040E339A0A7D2224819A550BBB4596279F67", "sha256-fingerprint": "d78933fa946cb71810111876049defa4feb6820c319c69918ba925b463bbd11c" }, "renew": false } ] }

Conclusion


In this tutorial, you learned how to secure Apache with mod_md Let’s Encrypt module to issue and auto-renew free TLS/SSL certificate on Ubuntu Linux 20.04 LTS server. For more information, see mod_md documentation here.

This entry is 2 of 2 in the Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 20.04 Tutorial series. Keep reading the rest of the series:
  1. How to install Apache on Ubuntu 20.04 LTS
  2. Secure Apache with mod_md Let’s Encrypt on Ubuntu 20.04 LTS
ADVERTISEMENTS
Posted by: Vivek Gite


The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.
 
  • Like
Reactions: SolarWinds