Securing Apache Web Server with mod_security 2.5.6
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, 2008). 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 “parallel text matching, Geo IP resolution, credit card number detection, support for content injection, automated rule updates, scripting, as well as many others.” (ModSecurity, 2008) 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  as of writing this article the version of mod_security is 2.5.6. 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 2.1.
linux-9sl8:/usr/src # md5sum modsecurity-apache_2.5.6.tar.gz eb9e80a232269378752aa5b81f3e99f8 modsecurity-apache_2.5.6.tar.gz
Figure 2.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.
Verifying 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 pgp.mit.edu website, the command to install Ivan’s PGP key is shown in Figure 2.2.
linux-9sl8:/usr/src # gpg --keyserver pgp.mit.edu --recv-key 971B7E08 gpg: requesting key 971B7E08 from hkp server pgp.mit.edu gpg: key 971B7E08: public key "Ivan Ristic <firstname.lastname@example.org>" imported gpg: no ultimately trusted keys found gpg: Total number processed: 1 gpg: imported: 1
Figure 2.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.3.
linux-9sl8:/usr/src # gpg modsecurity-apache_2.5.6.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 <email@example.com>" 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.3: 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.4.
linux-9sl8:/usr/src # gpg --verify modsecurity-apache_2.5.6.tar.gz.asc modsecurity-apache_2.5.6.tar.gz gpg: Signature made Wed 11 Apr 2007 18:09:39 BST using DSA key ID 971B7E08 gpg: Good signature from "Ivan Ristic <firstname.lastname@example.org>" 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.4: 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 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).
|libxml2-devel||Includes files and libraries mandatory for development.|
|apache2-devel||Header and include files.|
|pcre-devel||A library for Perl-compatible regular expressions.|
|curl-devel||Headers files for cURL development.|
Table 1: mod_security dependencies.
The packages listed in Table 1 can be installed with the “yast sw_single” command which will provide a curses based interface or the “yast2 sw_single” command which will provide a GUI (Graphical User Interface), in this article we will be using the “yast sw_single” command from the command line as shown in Figure 3.1.
linux-9sl8:/usr/src # yast sw_single
Figure 3.1: Launching YaST to install the dependencies.
Now that we have installed all of the dependencies that mod_security requires we can begin to decompress the source code archive, 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.1 shows the command used to decompress the source files.
linux-9sl8:/usr/src # tar zvxf modsecurity-apache_2.5.6.tar.gz modsecurity-apache_2.5.6/ modsecurity-apache_2.5.6/apache2/ modsecurity-apache_2.5.6/apache2/.deps modsecurity-apache_2.5.6/apache2/configure modsecurity-apache_2.5.6/apache2/apache2.h ... ...
Figure 4.1: Decompressing the mod_security archive.
Once the compressed tarball archive has been decompressed you should have a directory similar to “modsecurity-apache_2.5.6/apache2/” within your current working directory. The “modsecurity-apache_2.5.6/apache2/” directory contains the mod_security source code which needs to be compiled.
Compiling mod_security source code
The first step to compiling the mod_security source code is to change into the “modsecurity-apache_2.5.6/apache2/” directory and issue the “./configure” command as shown in Figure 4.2.
linux-9sl8:/usr/src/modsecurity-apache_2.5.6/apache2 # ./configure --with-apxs=/usr/sbin/apxs2
Figure 4.2: Configuring mod_security before building the source.
Once the configuration script has run successfully you can issue a “make” and “make install” command to install mod_security as shown in Figure 4.3.
linux-9sl8:/usr/src/modsecurity-apache_2.5.6/apache2 # make && make install
Figure 4.3: Installing mod_security.
Once mod_security has installed successfully and you got no errors when compiling you can move on to 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/libxml2.so” as shown in Figure 5.1.
... ... ### 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/libxml2.so ... ...
Figure 5.1: 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 5.2.
... ... 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 5.2: 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 5.3.
linux-9sl8:/etc/apache2 # service apache2 configtest Syntax OK
Figure 5.3: 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 6.1. 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”
# 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 6.1: 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  There are a number of example configuration files provided with the mod_security source code.
The configuration file in Figure 6.1 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 6.2.
linux-9sl8:/etc/apache2 # chmod 644 mod_security.conf linux-9sl8:/etc/apache2 # chown root.root mod_security.conf linux-9sl8:/etc/apache2 # ls -l mod_security.conf -rw-r--r-- 1 root root 799 2008-08-26 21:00 mod_security.conf
Figure 6.2: 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 6.3 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/libxml2.so # Mod_security policy file Include /etc/apache2/mod_security.conf
Figure 6.3: 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 6.4.
linux-9sl8:/etc/apache2 # service apache2 configtest Syntax OK
Figure 6.4: 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 6.5.
linux-9sl8:/etc/apache2 # service apache2 start Starting httpd2 (prefork) done
Figure 6.5: 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 6.6.
linux-9sl8:/etc/apache2 # telnet 127.0.0.1 80 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. GET / HTTP 1.1 HTTP/1.1 403 Forbidden Date: Tue, 26 Aug 2008 20:01:29 GMT Server: Microsoft IIS Vary: accept-language,accept-charset Accept-Ranges: bytes Connection: close Content-Type: text/html; charset=iso-8859-1 Content-Language: en Expires: Tue, 26 Aug 2008 20:01:29 GMT ... ... Connection closed by foreign host.
Figure 6.6: Checking the server signature.
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  as there are guides and reference manuals on mod_security so you can take advantage of all its features.
 Breach Security Inc, http://www.modsecurity.org/
 Breach Security Inc, http://www.modsecurity.org/documentation/index.html
 Netcraft, http://news.netcraft.com/archives/2008/06/22/june_2008_web_server_survey.html