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
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 pgp.mit.edu website, the command to install Ivan’s PGP key is shown in Figure 2.
damian@linux-1reo:~> 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 <ivanr@webkreator.com>" imported gpg: no ultimately trusted keys found gpg: Total number processed: 1 gpg: imported: 1
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 <ivanr@webkreator.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
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 modsecurity-apache_2.1.1.tar.gz gpg: Signature made Wed 11 Apr 2007 18:09:39 BST using DSA key ID 971B7E08 gpg: Good signature from "Ivan Ristic <ivanr@webkreator.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
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
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 modsecurity-apache_2.1.1/ modsecurity-apache_2.1.1/apache2/ ... ... modsecurity-apache_2.1.1/CHANGES modsecurity-apache_2.1.1/README.TXT
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 -Wsign-compare -DWITH_LIBXML2 -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -DAP_DEBUG -DSSL_EXPERIMENTAL_ENGINE -DMAX_SERVER_LIMIT=200000 -DLDAP_DEPRECATED -I /usr/include/libxml2 -I/usr/include/apache2 -I. -I/usr/include -I/usr/include/apr-1 -prefer-pic -c mod_security2.c && touch ... ... mod_security2.slo msc_multipart.slo 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 mod_security2.la /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
After you have compiled the source code and cleaned up any files left behind, you should have the “mod_security2.so” 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/libxml2.so” 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/libxml2.so ... ...
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" ... ...
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
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"
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
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/libxml2.so # Mod_security policy file Include /etc/apache2/mod_security.conf
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
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
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 127.0.0.1 Trying 127.0.0.1... Connected to 127.0.0.1. 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.
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.
References
[1] Breach Security Inc, http://www.modsecurity.org/
[2] Breach Security Inc, http://www.modsecurity.org/documentation/index.html
[3] Netcraft, http://news.netcraft.com/archives/2007/07/09/july_2007_web_server_survey.html
Comments
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’
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 !)
Hello,
This article was published one year ago [27 Jul 2007] I hope to get around to updating
this article.