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

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

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.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Life cycle management with Foreman and Puppet
    Virtual machines seem to be ideal for spare capacity. They are easy to create and remove – if only all those time-consuming administrative tasks like assigning IP addresses, setting up backups, and monitoring were more manageable. Having the right tools can help.
  • Setting up HTTP/2 on the Apache HTTP Server with PHP compatibility
    If you are running PHP applications, setting up HTTP/2 on the Apache HTTP Server can be a bit confusing because of some incompatibilities between the Apache HTTP/2 module and the Prefork multiprocessing module.
  • Setting up SSL connections on Apache 2
    To spoil the day for lurking data thieves, Apache administrators only need three additional directives – and a handful of commands.
  • Lua for Apache

    Lua is a small, lean, and fast scripting language – ideal for working with web servers. Version 2.4 of the Apache web server is the first to offer a matching module that has a few quirks – and pitfalls, if you dig more deeply.

  • Activate HTTP/2 on web servers
    HTTP/2 offers reduced website load times and other performance benefits, along with the promise of server push.
comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

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.

Learn More”>


		<div class=