Securing Apache Web Server with mod_security


The Apache web server is the most popular web server on the Internet today holding a “52.65% market share for top servers across all domains August 1995 – July 2007” (Netcraft, 2007). Apache is a possible gateway for malicious users to gather sensitive data and/or perform attacks against other hosts from your web server via an misconfiguration or a insecure web script (Perl, PHP, Python, etc). This is where mod_security steps in as it provides a layer of security which links into Apache providing rich features such as “event correlation, transaction scoring, anomaly detection, data persistence, a wealth of anti-evasion functions, regex back-references” (ModSecurity, 2007) for protecting Apache and eliminating possible security risks within insecure scripts.

Downloading & verifying mod_security

Mod_security can be downloaded from Breach Security Inc website [1] as of writing this article the version of mod_security is 2.1.1. The first step to installing mod_security is to check the integrity and authenticity of the mod_security compressed tarball archive. The two methods that can be used are regenerating the MD5 checksum and comparing it to the one Breach Security Inc provide or using PGP (Pretty Good Privacy), we are going to use both methods.

Verifying MD5 checksum

This method of integrity checking is the simplest as it requires the use of the “md5sum” command followed by the filename as shown in Figure 1.

damian@linux-1reo:~> md5sum modsecurity-apache_2.1.1.tar.gz
ab74ed5f320ffc4ed9f56487bf17c670 modsecurity-apache_2.1.1.tar.gz
Figure 1: Checking file integrity.

The MD5 checksum that is returned by the “md5sum” command can be compared to the checksum Breach Security Inc provide, if the checksums differ it is likely that the compressed tarball archive has been corrupt and/or has been tampered with.

Verify PGP signature

The second method of checking the integrity and authenticity of the compressed tarball archive is to download Ivan or Brian PGP key as stated on mod_security’s download page. The key can be downloaded from the website, the command to install Ivan’s PGP key is shown in Figure 2.

damian@linux-1reo:~> gpg --keyserver --recv-key 971B7E08
gpg: requesting key 971B7E08 from hkp server
gpg: key 971B7E08: public key "Ivan Ristic <>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:                         imported: 1
Figure 2: Importing Ivan’s public key.

Once the key has been successfully imported you will need to download the PGP signature file for the mod_security compressed tarball archive from the downloads page. Once the PGP signature file has been downloaded you can issue the “gpg” command to check the signature file, as shown in Figure 2.1.

damian@linux-1reo:~> gpg modsecurity-apache_2.1.1.tar.gz.asc
gpg: Signature made Wed 11 Apr 2007 18:09:39 BST using DSA key ID 971B7E08
gpg: Good signature from "Ivan Ristic <>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 3911 D9CE 2D0B 42F5 FFE3  7F79 59DD 2536 971B 7E08
Figure 2.1: Checking the signature file.

Now that Ivan’s public key has been imported as shown in Figure 2 and the mod_security compressed tarball archive signature file has been checked and shows that the signature file is good, as shown in Figure 3. It is now time to check the the integrity and authenticity of the mod_security compressed tarball archive which contains the source code for mod_security. The command we will use is “gpg” with the “–verify” qualifier as shown in Figure 2.2.

damian@linux-1reo:~> gpg --verify modsecurity-apache_2.1.1.tar.gz.asc
gpg: Signature made Wed 11 Apr 2007 18:09:39 BST using DSA key ID 971B7E08
gpg: Good signature from "Ivan Ristic <>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 3911 D9CE 2D0B 42F5 FFE3  7F79 59DD 2536 971B 7E08
Figure 2.2: Checking the integrity and authenticity of mod_security.

As you can see the compressed tarball archive that contains mod_security source code shows that the integrity of the file is good and is tarball archive is authentic. The next step that needs to be done before extracting the tarball archive is installing the dependencies that mod_security requires.

Mod_security dependencies

Mod_security has a few dependencies that need to be installed. The packages that are require are listed in Table 1, these dependencies are all development packages, as we are compiling from source, you may also want to check you have the “C/C++ Compiler and tools” installed (gcc, g++, etc).

Package Description
libxml2-devel Includes files and libraries mandatory for development.
apache2-devel Header and include files.
pcre-devel A library for Perl-compatible regular expressions.

Table 1: Mod_security dependencies.

The packages listed in Table 1 can be installed with the “yast” or the “yast2” command, in this article we will be using the “yast” command from the command line as shown in Figure 3.

linux-1reo:~# yast sw_single
Figure 3: Launching YaST to install the dependencies.

Installing mod_security

Now that we have installed all of the dependencies that mod_security requires we can begin to decompress the source code archive, edit the “Makefile”, compile the source and then deploy a policy file.

Decompressing the source file

The source code for mod_security is downloaded in a compressed tarball archive which can be extracted using the “tar” utility, Figure 4 shows the command used to decompress the source files.

linux-1reo:/usr/src # tar zvxf modsecurity-apache_2.1.1.tar.gz
Figure 4: Decompressing the source file.

Once the compressed tarball archive has been decompressed you should have a directory similar to “modsecurity-apache_2.1.1/apache2” within your current working directory. The “modsecurity-apache_2.1.1/apache2” directory contains the mod_security source code along with the “Makefile” that needs to be altered to contain SUSE’s paths and binaries.

Altering the “Makefile”

The “Makefile” is located within the “modsecurity-apache_2.1.1/apache2” directory. The variables that need to be alter are; “top_dir” as it currently points to “/app/apache22” which is incorrect, “APXS” value is also incorrect as SUSE uses a different command and “APACHECTL” value is also incorrect. The correct values are listen in Table 2.

Variable Value
top_dir /usr/share/apache2
APXS apxs2
APACHECTL apache2ctl

Table 2: “Makefile” variables and values.

Once these values have been altered and correctly set you can begin compiling the source code by issuing the command “make” followed by a “make install” which compiles the source code and produce binary files which are placed into there correct locations. The final step in compiling the source code is to clean up any files left behind by issuing the “make clean” command as shown in Figure 5.

linux-1reo:/usr/src/modsecurity-apache_2.1.1/apache2 # make 
/usr/lib/apr-1/build/libtool --silent --mode=compile gcc -pthread -O2 -g -Wuninitialized
-Wall -Wmissing-prototypes -Wshadow -Wunused-variable -Wunused-value -Wchar-subscripts
-I /usr/include/libxml2 -I/usr/include/apache2 -I. -I/usr/include -I/usr/include/apr-1
-prefer-pic -c mod_security2.c && touch
msc_multipart.c: In function ?multipart_init?:
msc_multipart.c:520: warning: passing argument 1 of ?ap_strstr? discards qualifiers
from pointer target type

linux-1reo:/usr/src/modsecurity-apache_2.1.1/apache2 # make install 
make[1]: Entering directory `/usr/src/modsecurity-apache_2.1.1/apache2'
/usr/lib/apr-1/build/libtool --silent --mode=install cp /usr/lib/apache2/
make[1]: Leaving directory `/usr/src/modsecurity-apache_2.1.1/apache2'

linux-1reo:/usr/src/modsecurity-apache_2.1.1/apache2 # make clean
make[1]: Entering directory `/usr/src/modsecurity-apache_2.1.1/apache2'
rm -f *.o *.lo *.slo *.obj *.a *.la
rm -rf .libs
make[1]: Leaving directory `/usr/src/modsecurity-apache_2.1.1/apache2'
rm -f *.o *.lo *.slo *.la *~ .libs
Figure 5: Compiling mod_security and cleaning up any files left behind.

After you have compiled the source code and cleaned up any files left behind, you should have the “” file located in the “/usr/lib/apache2” directory.

Enabling mod_security

Once mod_security has been compiled you can begin configuring Apache to load the module. The first file you will need to edit is the “httpd.conf” located in the “/etc/apache2” directory. The reason we have to edit this file is because we need to load the libxml2 file as this is a mod_security dependency, so under the heading “Global Environment” you need to add “LoadFile /usr/lib/” as shown in Figure 6.

### Global Environment ######################################################
# The directives in this section affect the overall operation of Apache,
# such as the number of concurrent requests.

# Load libxml2
LoadFile /usr/lib/
Figure 6: Apache httpd.conf file.

The next step is to have Apache load the mod_security module and the mod_unique_id module as it is another dependency for mod_security. The file that needs to be altered is “/etc/sysconfig/apache2”, within this file there is a variable called “APACHE_MODULES” that holds a list of modules that are to be loaded when Apache starts, you will need to add the following two values “unique_id” and “security2” as shown in Figure 6.1.

APACHE_MODULES="unique_id security2 actions alias auth_basic authn_file authz_host
authz_groupfile authz_default authz_user authn_dbm autoindex cgi dir env expires
include log_config mime negotiation setenvif ssl suexec userdir php5"
Figure 6.1: Apache modules to be loaded.

Once you had added the two modules to be loaded you can check the Apache configuration file by issues the “service” command as shown in Figure 6.2.

linux-1reo:~# service apache2 configtest
Syntax OK
Figure 6.2: Apache configuration test.

Now that mod_security is configure and setup you will need to create a policy file that will help protect your server from attacks.

Mod_security policy file

The configuration file we will be using is shown in Figure 7. This configuration file will also be saved in the “/etc/apache2” directory with the filename of “mod_security.conf”. The Apache “httpd.conf” file will also have to be altered again to include the “mod_security.conf” file.

# Basic configuration options
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off

# Handling of file uploads
# TODO Choose a folder private to Apache.
# SecUploadDir /opt/apache-frontend/tmp/
SecUploadKeepFiles Off

# Debug log
SecDebugLog /var/log/apache2/modsec_debug.log
SecDebugLogLevel 0

# Serial audit log
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ^5
SecAuditLogParts ABIFHZ
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log 

# Maximum request body size we will
# accept for buffering
SecRequestBodyLimit 131072

# Store up to 128 KB in memory
SecRequestBodyInMemoryLimit 131072

# Buffer response bodies of up to
# 512 KB in length
SecResponseBodyLimit 524288

# Set Server Signature
SecServerSignature "Microsoft IIS"
Figure 7: Basic mod_security configuration file.

This is a very basic configuration that is provided by Breach Security Inc. The extra variable I added was the “SecServerSignature” which makes users, attackers and bots think that the web server is Microsoft’s Internet Information Server. The variables that can be used in the configuration file can be found on mod_security’s website [1] There are a number of example configuration files provided with the mod_security source code.

The configuration file in Figure 7 also had the variables “SecDebugLog” and “SecAuditLog” values changed to suite the layout of the Apache server as logs are stored in the “/var/log/apache2” directory.

Once you are satisfied with the “mod_security.conf” file, save the configuration file in the “/etc/apache2” directory with the permissions “644” and with the user and group owner of root as shown in Figure 7.1.

linux-1reo:/etc/apache2 # chmod 644 mod_security.conf
linux-1reo:/etc/apache2 # chown root:root mod_security.conf
linux-1reo:/etc/apache2 # ls -l mod_security.conf
-rw-r--r-- 1 root root   771 Jul 16 07:30 mod_security.conf
Figure 7.1: Setting the correct file permissions.

Now that the “mod_security.conf” file has been created and has the appropriate permissions applied it is now time to include the “mod_security.conf” file in the Apache “httpd.conf” file. The keyword “Include” followed by the configuration file to be included in the Apache configuration is needed to be able to load the policy file. Figure 7.2 shows the “mod_security.conf” file being included.

### Global Environment ######################################################
# The directives in this section affect the overall operation of Apache,
# such as the number of concurrent requests.

# Load libxml2
LoadFile /usr/lib/

# Mod_security policy file
Include /etc/apache2/mod_security.conf
Figure 7.2: Apache “httpd.conf” with mod_security policy file enabled.

Once the “mod_security.conf” file has been included you should re-check the syntax for Apache to make sure there are no syntax errors. This can be done using the “service” command as shown in Figure 7.3.

linux-1reo:~# service apache2 configtest
Syntax OK
Figure 7.3: Checking Apache’s configuration syntax.

Now that the mod_security configuration file has been included and the syntax was reported as OK, you can start the Apache web server via the “service” or “rcapache2” command as shown in Figure 7.4.

linux-1reo:~# service apache2 start
Figure 7.4: Starting the Apache web server.

Once Apache has been started you can “telnet” into your web server and issue a “GET / HTTP/1.0” query. The “GET” query should return the status of your query along with a server signature, in our example it displays “Microsoft IIS” as shown in Figure 7.5.

linux-1reo:~# telnet
Connected to
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 200 OK
Date: Mon, 16 Jul 2007 11:11:32 GMT
Server: Microsoft IIS
Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT
ETag: "19b12-2c-4c23b600"
Accept-Ranges: bytes
Content-Length: 44
Connection: close
Content-Type: text/html

<html><body><h1>It works!</h1></body></html>Connection closed by foreign host.
Figure 7.5: Checking the server signature.

Final thoughts

Now that you have mod_security installed you can create and experiment with policy files to make your web server security much tighter. I would also recommend visiting Breach Security Inc website [2] as there are guides and reference manuals on mod_security so you can take advantage of all its features.


[1] Breach Security Inc,
[2] Breach Security Inc,
[3] Netcraft,

(Visited 1 times, 1 visits today)


  • anonymous says:

    it is not possible to compile and install mod-security correctly on SLES10SP2. When installing the module, the apache only produces segfaults !
    During the “make test” the following error occurs:
    undefined reference to `ap_strstr’

  • Anonymous says:

    this manual is outdated:
    mod_security 2.1.1 is not available anymore. and with the recent suse-webservers (SLES 10 SP2 // Opensuse) the actual mod_security (2.5.6) does not work anymore (apache segfaults !)

  • DamianMyerscough says:


    This article was published one year ago [27 Jul 2007] I hope to get around to updating
    this article.

  • Leave a Reply

    Your email address will not be published. Required fields are marked *