Securing Apache2 on Linux | Joachim De Zutter
Update Apache2 to the latest version by rebuilding it from the source
wget http://*.apache.org/dist/apr/apr-*.*.*.tar.gz
tar xzvf apr-*.*.*.tar.gz
cd apr-*.*.*
./configure
make
make install
cd ..
wget http://*.apache.org/dist/apr/apr-util-*.*.*.tar.gz
tar xzvf apr-util-*.*.*.tar.gz
cd apr-util-*.*.*
./configure --with-apr=/usr/local/apr
make
make install
cd ..
wget http://*.apache.org/dist/httpd/httpd-*.*.*.tar.gz
tar xzvf httpd-*.*.*.tar.gz
cd httpd-*.*.*
./configure
make
make install
Hide Apache2 version information

Modify /usr/local/apache2/conf/httpd.conf so it contains

ServerTokens Prod

so that no version information will be sent in HTTP responses.

Modify /usr/local/apache2/conf/httpd.conf so it contains

ServerSignature Off

so that no version information will be displayed on error pages.

Restart the Apache2 server with sudo apache2ctl restart.

Disable indexes

In /usr/local/apache2/conf/httpd.conf remove Indexes for folders where listing of (sub)folder files is not necessary.

Restart the Apache2 server with sudo apache2ctl restart.

Enable logging of HTTP request header fields

In /usr/local/apache2/conf/httpd.conf switch to combined logging:
<IfModule log_config_module>
    #
    # The following directives define some format nicknames for use with
    # a CustomLog directive (see below).
    #
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    #
    # The location and format of the access logfile (Common Logfile Format).
    # If you do not define any access logfiles within a <VirtualHost>
    # container, they will be logged here.  Contrariwise, if you *do*
    # define per-<VirtualHost> access logfiles, transactions will be
    # logged therein and *not* in this file.
    #
    #CustomLog "logs/access_log" common

    #
    # If you prefer a logfile with access, agent, and referer information
    # (Combined Logfile Format) you can use the following directive.
    #
    CustomLog "logs/access_log" combined
</IfModule>
so that the referer and user agent of HTTP clients will be logged.

It is possible to define a custom log format which also logs the X-Forwarded-For client header field in order to find the IP address of systems behind a proxy, provided that the proxy supplied this information correctly:
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" custom
...
    CustomLog "logs/access_log" custom
Restart the Apache2 server with sudo apache2ctl restart.

Disable unused shared modules (*.so)

Since we don't want directory contents to be shown, disable the autoindex module by modifying /usr/local/apache2/conf/httpd.conf so it contains:

#LoadModule autoindex_module modules/mod_autoindex.so

Instead of

LoadModule autoindex_module modules/mod_autoindex.so

In case we are not interested in having a status page which provides information on server activity and performance, disable the status module by modifying /usr/local/apache2/conf/httpd.conf so it contains:

#LoadModule status_module modules/mod_status.so

Instead of

LoadModule status_module modules/mod_status.so

In case basic HTTP authentication is not used, disable the auth_basic module by modifying /usr/local/apache2/conf/httpd.conf so it contains:

#LoadModule auth_basic_module modules/mod_auth_basic.so

Instead of

LoadModule auth_basic_module modules/mod_auth_basic.so

Restart the Apache2 server with sudo apache2ctl restart.

Check the list of loaded modules with:

apachectl -M