« Previous 1 2 3 4 Next »
Harden your Apache web server
Batten the Hatches
Let's Encrypt with mod_md
The managed domain module, mod_md
, entered Apache in version 2.4.30 and is available as of Ubuntu 20.04 and Debian 10. Additionally, the mod_watchdog
module handles periodic tasks. You can use mod_md
to integrate the Automatic Certificate Management Environment (ACME), which is responsible for issuing certificates directly in the Apache configuration. The simplest case will have syntax as in Listing 4. This configuration tells the server to obtain a new certificate automatically from Let's Encrypt, which the virtual host then uses. The renewal process is also automated. Which Let's Encrypt challenge takes effect depends on the port on which Apache is listening. For port 80, you can use the HTTP-01 challenge; otherwise, use TLS-ALPN-01 on port 443.
Listing 4
mod_md Configuration
MDomain example.org MDCertificateAgreement accepted <VirtualHost *:443> ServerName www.example.com ServerAdmin hostmaster@example.com SSLEngine on </VirtualHost>
A wildcard certificate requires a DNS-01 challenge, for which you need to specify a script (i.e., in /usr/bin/acme-setup-dns
) that matches the DNS records:
MDChallengeDns01 /usr/bin/acme-setup-dns
This script has to support two calls:
acme-setup-dns setup example.com <challenge-data> acme-setup-dns teardown example.com
You also need to provide a valid email address in the ServerAdmin
directive, which is stipulated as a mandatory requirement by Let's Encrypt and which the certification authority uses for important notifications.
The Apache log reveals that a new certificate has been obtained:
[Fri Jan 01 13:41:06.880247 2020] [md:notice] [pid 776:tid 139942708430592] AH10059: The Managed Domainwww.example.com has been setup and changes will be activated on next (graceful) server restart.
Afterward, at least a graceful restart is required. When a certificate is renewed, an automatic restart with cronjob makes sense.
The mod_md
module extends mod_status
to include the md-status
section, which means you get JSON output for a specific domain. To query this, use https://www.example.com/md-status/example.com
. The special status page can be enabled with the configuration:
<Location "/md-status"> SetHandler md-status Require ip 192.0.2.0/24 </Location>
In the default setting, a certificate status can also be retrieved with https://www.example.com/.httpd/certificate-status
. You can disable access to it with MDCertificateStatus off
.
If you don't want to use Let's Encrypt certificates, you can use the mod_md
module for commercial certificate authorities. Some providers now support the standardized ACME protocol.
Web Application Firewall
The Apache mod_security2
module implements a full-fledged web application firewall (WAF). Because it is integrated directly into Apache, it also works independently regardless of whether a connection is encrypted with HTTPS. The WAF can manipulate the request or the web server's response directly. The module can therefore intervene and provide protection against an attack before the request reaches the web application.
On Ubuntu and Debian, the installation is very simple, thanks to a pre-built module in the repository. To install, run:
apt install libapache2-mod-security2
You then need a configuration file named /etc/modsecurity/modsecurity.conf
. However, that's it for the easier part of the setup. The mod_security2
module is extremely powerful, so I can only provide a brief overview at this point.
By default, the module starts in detection mode (SecRuleEngine
DetectionOnly
), which allows the web application to continue working as usual so you can check ruleset matches. On Debian and Ubuntu, you can find the logfile in /var/log/apache2/modsec_audit.log
.
You can create all the rules and allow and block lists. However, you also can find free and well-maintained default rules, such as the OWASP ModSecurity Core Rule Set. According to its own specifications, it offers protection against many different types of attacks [9].
Chroot Versus Containers
The mod_unixd
module and the ChrootDir
directive let you run Apache in a chroot environment. For a basic static web server, this is quite simple to achieve.
Things gets more complex if you want to use scripting languages in the chroot, too, and will work with mod_php
, even in the chroot environment. However, you will face restrictions with certain functions (e.g., the mail
command), for which you then need additional libraries and configuration files in the chroot directory, quickly making the whole project more error-prone.
As an alternative to the PHP module, the PHP-FPM FastCGI variant comes with its own chroot option. The Apache mod_security2
module offers a SecChrootDir
directive for the same purpose, but the overhead remains similar.
Independent of the chroot option, isolation in containers is also a good idea. Technology-wise, you can use either Docker containers or Linux containers (LXC/LXD), which allow separate Apache instances for individual applications. If you have to save IP addresses with virtual hosts, it can make sense to connect an upstream proxy that can handle Server Name Indication (SNI) for HTTPS connections in such a scenario.
« Previous 1 2 3 4 Next »
Buy this article as PDF
(incl. VAT)
Buy ADMIN Magazine
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Most Popular
Support Our Work
ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.