Hardening Apache on an unmanaged VPS#

Published on May 22, 2022 by Fayçal Alami-Hassani @gnufcl@fosstodon.org

Hardening Apache on an unmanaged VPS

Picture by J4747 under CC BY License#

This guide is a follow-up to the post published last week about Migrating Joomla from shared hosting to an unmanaged VPS. In this tutorial, you will learn how to implement a set of security measures to protect your Apache web server on Debian-based Linux systems.

Prerequisites#

This tutorial assumes that you already have the following:

  • LAMP stack installed on your VPS server. LAMP is short for “Linux + Apache + MySQL + PHP”.

  • Non-root user with sudo privileges on your VPS server.

  • SSH access to your VPS server.

Before you follow this guide, make sure to configure your environment accordingly.

Running Apache with an unprivileged user#

The “principle of least privilege” is a security best practice in the context of server administration. According to this principle, you should grant users only the strict minimum of permissions they need to perform their tasks. Therefore, running your Apache web server with a non-root user helps you prevent abusive access to the system.

To manage user and group privileges on your server, you need to access the envvars file. This file contains the environment variables of your Apache web server.

  1. First, type the following command in your terminal:

    $ sudo nano /etc/apache2/envvars
    
  2. In the file that opens, navigate to the following lines:

    1# Since there is no sane way to get the parsed apache2 config in scripts, some
    2# settings are defined via environment variables and then used in apache2ctl,
    3# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
    4export APACHE_RUN_USER=apache
    5export APACHE_RUN_GROUP=apache
    
  3. Set the variables APACHE_RUN_USER and APACHE_RUN_GROUP to a non-root user and group, respectively.

    The table below illustrates some possible values for a non-root user and group:

    ↓ Value Pair / Environment Variable →

    APACHE_RUN_USER

    APACHE_RUN_GROUP

    VALUE PAIR 1

    apache

    apache

    VALUE PAIR 2

    nobody

    nogroup

    VALUE PAIR 3

    www-data

    www-data

Hiding your operating system and Apache version#

Each time a user connects to your website, your server sends so-called response headers to the user’s browser. Response headers are HTTP headers containing metadata that is not related to the main message being exchanged between the client and your server.

In the default configuration, your web server exposes sensitive information about your infrastructure such as the operating system (OS) and the Apache version installed on the server.

You can check this by using a tool such as cURL. In your terminal, type the following command:

$ curl -IL your-domain-name

You should then get an output like the one below. Note that the details of your OS and Apache version appear on lines number 3 and 9 under the Server entry:

 1HTTP/1.1 301 Moved Permanently
 2Date: Sun, 22 May 2022 19:57:25 GMT
 3Server: Apache/2.4.25 (Debian)
 4Location: https://your-domain-name/
 5Content-Type: text/html; charset=iso-8859-1
 6
 7HTTP/1.1 200 OK
 8Date: Sun, 22 May 2022 19:57:25 GMT
 9Server: Apache/2.4.25 (Debian)
10Expires: Wed, 17 Aug 2005 00:00:00 GMT
11Last-Modified: Sun, 22 May 2022 19:57:25 GMT
12Cache-Control: xxx, xxx, xxx-xxx, xxxxxxx, xxxxxxxx
13Pragma: no-cache
14X-Content-Type-Options: nosniff
15X-Frame-Options: sameorigin
16Content-Type: text/html; charset=utf-8
  1. To hide your operating system and Apache version, you need to adjust the settings of your apache2.conf file. To revert your settings to their initial state in case of a faulty configuration, you should first make a backup of this file with the following command:

    $ sudo cp /etc/apache2/apache2.conf /etc/apache2/apache2_bak.conf
    
  2. Next, open the apache2.conf file by typing this command in your terminal:

    $ sudo nano /etc/apache2/apache2.conf
    
  3. In the file that opens, scroll down to the bottom and add the following two lines:

    ServerTokens Prod
    ServerSignature Off
    
  4. Press Ctrl + O to save your changes and Ctrl + X to close the nano editor.

  5. Run the following command to restart Apache:

    $ sudo systemctl restart apache2
    
  6. In your terminal, retype the following command:

    $ curl -IL your-domain-name
    
  7. The new output should now look like this:

 1HTTP/1.1 301 Moved Permanently
 2Date: Sun, 22 May 2022 19:57:25 GMT
 3Server: Apache
 4Location: https://your-domain-name/
 5Content-Type: text/html; charset=iso-8859-1
 6
 7HTTP/1.1 200 OK
 8Date: Sun, 22 May 2022 19:57:25 GMT
 9Server: Apache
10Expires: Wed, 17 Aug 2005 00:00:00 GMT
11Last-Modified: Sun, 22 May 2022 19:57:25 GMT
12Cache-Control: xxx, xxx, xxx-xxx, xxxxxxx, xxxxxxxx
13Pragma: no-cache
14X-Content-Type-Options: nosniff
15X-Frame-Options: sameorigin
16Content-Type: text/html; charset=utf-8

Note that your OS and Apache version details have disappeared from lines 3 and 9. The Server entry only shows Apache without any further details.

Disabling open directory listings#

If a directory inside your filesystem lacks an index file such as index.html or index.php, the web server automatically generates a listing of that particular directory. When this feature is enabled, intruders and eavesdroppers can explore the content of your folders to spot any existing vulnerabilities.

A directory without an index file

An example of an open directory listing#

To protect your directory content against curious eyes, you need to modify the configuration of your apache2.conf file.

  1. Open the file with your nano editor by typing the following command:

    $ sudo nano /etc/apache2/apache2.conf
    
  2. In the file that opens, scroll down to the following directive block:

    <Directory /var/www/>
            Options Indexes FollowSymLinks
            AllowOverride None
            Require all granted
    </Directory>
    
  3. Add a minus sign “-” before the keywords Indexes and FollowSymLinks to prevent Apache from generating open directory listings and following symbolic links. The result should look like this:

    <Directory /var/www/>
            Options -Indexes -FollowSymLinks
            AllowOverride None
            Require all granted
    </Directory>
    
  4. Press Ctrl + O to save your changes and Ctrl + X to close the nano editor.

  5. Restart Apache with the following command:

    $ sudo systemctl restart apache2
    

Installing a web application firewall#

A web application firewall (WAF) protects your applications from malicious attacks by scanning and filtering HTTP traffic. ModSecurity is an open source WAF that provides multiple security features including monitoring, logging, and real-time traffic inspection. You can install ModSecurity on your Apache web server with the free module mod_security2.

  1. To install mod_security2 on Debian-based distributions, type the following command in your terminal:

    $ sudo apt install lib-apache2-mod-security2
    
  2. Check if mod_security2 is up and running on your system by running the command:

    $ sudo apachectl -M | grep --color security
    

    You should get the following output:

    $ security2_module (shared)
    

    Note

    When you install mod_security2 for the first time, ModSecurity runs in detection-only mode. That is, it detects and logs suspicious activity, and no more than that. To block unwanted traffic, you need to modify the default ModSecurity configuration file: modsecurity.conf-recommended.

  3. Rename the file modsecurity.conf-recommended to modsecurity.conf by typing the command below:

    $ mv /etc/modsecurity/modsecurity.conf{-recommended,}
    
  4. Open the new file with your nano editor:

    $ nano /etc/modsecurity/modsecurity.conf
    
  5. In the file that opens, navigate to the directive:

    SecRuleEngine DetectionOnly
    
  6. Replace the value DetectionOnly by the new value On.

  7. Press Ctrl + O to save your changes and Ctrl + X to close the nano editor.

  8. Restart Apache with the following command:

    $ sudo systemctl restart apache2
    

From now on, ModSecurity will also block unwanted traffic.