You are on page 1of 13

Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.

html

Apache 2.0 Hardening Guide

Technical Reference: Apache 2.0 DMZ Secure Server Install

Overview
This document is a guide to installing and hardening an Apache 2.0 web server to common security
standards. It will guide you through practical measures to harden your Apache server, by way of example.

Because a web server is often placed at the edge of the network, it is one of the most vulnerable services to
attack. Therefore, it’s vital that you follow this guide to ensure that:

1) The opportunity to compromise the web server is limited


2) Should the web server be compromised, the damage potential to the rest of the network, data, and
systems is limited.

1. Prepare the host operating system

1.1 Install and secure the host operating system.

Follow the hardening guidelines in the The Center for Internet Security. Hardening the host O/S
ensures that, should someone compromise the security of your web server, the amount of damage
that they could inflict will be minimized.

1.2 Create the directories to hold the Apache files

It’s important to separate the binaries /bin, docs (/htdocs), and logs (/logs) into separate
partitions on the system. You can choose whatever root you want, but this example will use
/opt/apache2 as the root directory for the Apache web server.

1.3 Create the host groups for administering and running the server.

Create a distinct group for all the users who will have permission to change the configuration, start,
and stop the web server. For example, if you want to call the group “webadmin”, create it like this:

# groupadd webadmin

Create a distinct group for the web server user – no one will actually log into this group, but it will
only be used to hold the userid which will run the web server. For example, if you want to call that
group “webserv”, create it like this:

# groupadd webserv

Take note that you should not create a “web developer” group on this host. Since this is a hardened
production host you must not provide web developers login accounts on this system. Instead,
developers should deploy documents and code to the server using your code/content deployment
system, such as Kintana’s Apps*Integrity.

1.4 Create an unprivileged host user id to run the server.

Never run the web server as root; if the web server is ever compromised, the attacker will have
complete control over the system. Instead, the best way to reduce your exposure to attack when
running a web server is to create a unique unprivileged userid for the server application. The userid
nobody is often used for this purpose, but a userid and group that are unique to the web server is a
more secure solution.

By default the web server uses privileged ports (port 80 and 443) and, when configured for secure

1 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

operation, must have root privileges to open its log files and start the dæmon. (Therefore, the web
server daemon will have to be started as “root”, unless you configure it to use a port higher than
1024.) Once the server's startup tasks are complete, all active instances can run as the unprivileged
user.

Use the following command line entries as patterns for creating a group and user for the web server.
Here’s an example if you were to use “webserv” as the user:

# useradd -d /opt/apache2/htdocs -g webserv -c "Web Server"


webserv
1.5 Lock down the web server account

It’s important that no one can successfully execute a password guessing attack against this account,
so in this step, we’ll restrict this account so that no one can log into it.

1.5.1 Issue this command to lock the password for the web server account:

# passwd –l webserv

Password changed.

1.5.2 To be sure the account is locked, issue the command:

# grep webserv /etc/shadow

…a :!: at the beginning of the line indicates that the password is locked.

1.5.3 Issue this command to remove the shell for this account:

# usermod –s /bin/false webserv

1.5.4 To be sure the account is locked, issue the command:

# grep webserv /etc/passwd

…/bin/false at the end of the line indicates that the shell is set to a non-existent
shell.

1.5.5 Test the web server account to be sure you can’t login. Issue this command to try to
log in:

> login webserv

2. Download and verify Apache source code

By default, web servers return information about the product and version they are running in the Server
variable of the HTTP header. This information can be very useful to hackers, enabling them to target
attacks to that specific server. To prevent that information from being returned from the web server, this
step shows you how to modify that header and build your own copy of the web server.

Because web servers often host sensitive information, or allow users to log in with plain-text passwords, it’s
important to encrypt the HTTP traffic. Therefore, this section will show you how to configure mod_ssl on
your web server.

Note: Don’t build the web server on your production, hardened host. Build it on a staging or
development server (with identical O/S), and then copy it to your production host.

2 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

These steps will guide you through downloading Apache source code, validating it, compiling it, and
installing it. We don’t recommend use of pre-compiled or DSO versions. DSO versions may allow a hacker to
introduce new “features” without having to recompile the code.

If you intend to add other module to your Apache web server installation, repeat the validation steps below
for each module you add.

2.1 Download the latest version of Apache 2.0

Ensure that you retrieve the latest copy, so that you have cumulative bug fixes and security
patches. You can download it from the Apache site.

From here, download four files:

1) The Apache source code itself, called something like httpd-2.0.45.tar.gz.


2) The PGP keys for the Apache signers: a file named “KEYS”
3) The PGP key for this source distribution, called something like httpd-2.0.45.tar.gz.asc
4) The MD5 checksum for this source distribution, called something like httpd-2.0.45.tar.gz.md5

wget http://www.apache.org/dist/httpd/httpd-2.0.45.tar.gz
wget http://www.apache.org/dist/httpd/KEYS
wget http://www.apache.org/dist/httpd/httpd-2.0.45.tar.gz.asc
wget http://www.apache.org/dist/httpd/httpd-2.0.45.tar.gz.md5

2.2 Verify PGP signature for the Apache source

To ensure that you have an authentic version from the Apache Group, and that it’s not been
tampered with (remember, there are many mirrors from which you can download the Apache
source), you should check the PGP signature. If you don’t have PGP installed on this server, you can
validate these files on another machine.

a) If you don’t already have them in your PGP keyring, import the public keys from the Apache
Group into your keyring:

~> pgp –ka KEYS

b) Check the PGP signature:

~> pgp httpd_2.0.45.tar.gz

…if the signature is correct, you should get something similar to this:

-- CUT --
File 'httpd-2.0.45.tar.gz.asc' has signature, but with no text.
Text is assumed to be in file 'httpd-2.0.45.tar.gz'.
Good signature from user "Justin R. Erenkrantz
<justin@erenkrantz.com>".
Signature made 2003/03/31 07:49 GMT

WARNING: Because this public key is not certified with a trusted


signature, it is not known with high confidence that this public key
actually belongs to: "Justin R. Erenkrantz <justin@erenkrantz.com>".

The fact that it says, “Good Signature from…” is what we’re looking for here. The
WARNING statement indicates that we’ve not verified this signature with a 3 rd party, which
is ok here.

2.3 Verify the MD5 checksum for the Apache source.

3 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

MD5 is a way to validate the integrity of the file itself, much more reliable than checksum and
similar methods. Normally, mismatches in the MD5 checksum from the Apache source are the result
of download errors or file corruption. If you don’t have MD5 on your system, you can download it
from here.

Compare the results of these two commands – visually inspect them to ensure they match (if they
don’t, download it again):

~> pwd
/usr/local/build

~> cat httpd-2.0.45.tar.gz.md5


MD5 (httpd-2.0.45.tar.gz) = 1f33e9a2e2de06da190230fa72738d75

~> md5 apache_1.3.27.tar.gz


MD5 (httpd-2.0.45.tar.gz) = 1f33e9a2e2de06da190230fa72738d75

2.4 Extract the zipped Apache source file.

Finally, you need to unzip and untar the source file.

~> /pwd
/usr/local/build

~> tar xvfz httpd-2.0.45.tar.gz

This will create a new directory under your current one, named “httpd-2.0.45”.

3. Create SSL certificates

SSL support requires an SSL library on your system, such as OpenSSL. If you’re not sure how to find
and install it, look at the Apache 1.3 hardening guide. This section will walk you through configuring
your SSL certificate for encrypting your HTTP traffic. It will help you build a validated certificate and
install it on your web server. We’ll add the configured certificates to the Apache configuration in the
next step.

3.1 Create a key and certificate request for your web server

Using OpenSSL, the following command will create a 1024-bit private key named, “private.key” and
generate a certificate signing request (CSR). You need to have the CSR signed by a Certificate
Authority (CA) who can validate your identity. When prompted to input information, note the
answers in bold print below. (Answer the prompts with the information relevant for your server, of
course).

Note: If you provide a challenge password, you will be unable to start the web server unattended.
We don’t recommend providing a challenge password, just leave it blank.

~> pwd
/usr/local/build

~> openssl req -nodes -newkey rsa:1024 -keyout /usr/local/build/server.key


-out /usr/local/build/server.crt

Using configuration from /usr/share/ssl/openssl.cnf


Generating a 1024 bit RSA private key
................++++++
.......++++++
writing new private key to 'server.key'

4 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:NC
Locality Name (eg, city) []:RTP
Organization Name (eg, company):XianCo Systems, Inc.
Organizational Unit Name (eg, section) []:InfoSec
Common Name (eg, YOUR name) []:xianshield.xianco.com
Email Address []:webmaster@xianshield.xianco.com

Please enter the following 'extra' attributes


to be sent with your certificate request
A challenge password []: <blank>
An optional company name []: <blank>

Most importantly, make sure your “Common Name” above matches the DNS name of your server.
The locale information is less important, but we think it’s best to use the locality of the server itself.

3.2. Submit CSR for validation/signing by a CA.

Next, you need to submit your CSR for signing by a CA. This will eliminate the “warning dialog” that a
browser will pop up when a user accesses your site. This is because the user’s browser has a set of
trusted CAs that will prevent you from being notified if the web server’s site certificate is signed by a
CA you’ve trusted in your browser already (such as Verisign or DST). In this example, we will submit
the request to your company’s CA for signing. (You can use another CA if you want).

Send your request for a certificate to the CA. Include your name, your web server (Apache, in this
case) your OS, and of course, the .csr (certificate signing request).

5 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

3.3 Rename your certificate files

The names aren’t important, they just have to match what’s in conf/ssl.conf. You will
receive 2 files from the PKI team. The first file will be your server certificate (and will
probably be named <server name>.cer), the 2nd file is the certificate chain. Here, we’ll
rename them to fit what’s specified in conf/ssl.conf.

mv “XianCo CA (01-03).cer” ca.crt


mv xianshield.cer server.crt

3.4 Copy certificates to your server.

Since you received these certs via email, and they’re now sitting on your laptop, we need to
copy both server.crt and ca.crt to the server. We’ll copy them up to /usr/local
/build. We’ll move them both to the appropriate locations under conf/ssl.conf later.

scp *.crt xianshield:/usr/local/build/.

4. Configure and build the Apache Server

In this section, we’ll configure Apache with SSL and mod_ldap support. As of Apache V2, these are
both included modules, and don’t require a separate download.

In order to customize Apache to the extent necessary, we need to download the source for the latest
version of Apache. Once that’s complete, we’ll configure and test it.

6 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

4.1 Alter the Apache version

We want to remove/modify the default HTTP response header parameter for the “Server:” token to
hide the identity of our web server. (You’d be surprised how many vulnerability scanners are looking
for specific versions of Apache.) To do this, we must open a header file (httpd.h) prior to
compiling the server. To do this, edit the ap_release.h file located in
${ApacheSrcDir}/include

~> pwd
/usr/local/build/httpd-2.0.45/include

~> vi ap_release.h

#define AP_SERVER_BASEVENDOR "Apache Software Foundation" � Change this…


#define AP_SERVER_BASEPRODUCT "Apache" � and this

These are the lines you want to change; change these to remove references to Apache. We’ll hide
the actual version using the ServerTokens directive in the httpd.conf file.

Example:

#define SERVER_BASEVENDOR "Network Services"


#define SERVER_BASEPRODUCT "Networks, Inc."

4.2 Configure Apache software for compilation

There are a few standard modules that should be disabled when you set up the Apache web server.

Modules to disable
Generally, the following modules make it easier to configure/support your web server but also give
too much information to attackers. We recommend that you disable the following default modules
for your production server:

info: gives out too much information about your web server to potential attackers.
status: gives out server stats via web pages
autoindex: provides directory listings when no index.html file is present
imap: provides server-side mapping of index files
include: provides server-side includes (.shtml files)
userdir: translates URLs to user-specific directories
auth: you won’t need it – you’ll set up authentication against LDAP via mod_ldap

Modules to enable
Here are two modules that will provide strong authentication and encryption for your web server. If
you have any protected content on your web server, it’s important that you only allow your users to
access it over SSL, otherwise your user passwords will be sent in clear text, subject to snooping.

ssl: Encrypts the traffic from the browser to the web server – an important means of protecting
login passwords and sensitive data.
auth_ldap: Allows you to validate passwords against ldap.xianco.com or other LDAP.

A word about LDAP authentication


It’s important that you don’t set up your own userid/password store, since it propagates passwords
into insecure locations. Instead, you should modify your configuration to defer authentication to a
central store, such as a centrally maintained LDAP. To authenticate against an LDAP store, you need
to compile Apache with support. In order to use mod_ldap, you’ll need LDAP libraries installed on

7 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

your system. You can use OpenLDAP or Netscape Directory SDK for the LDAP client libraries.

Configuration commands
Here’s how to configure Apache with these options:

~> pwd

/usr/local/build/httpd-2.0.45

~> sudo ./configure –-prefix=/opt/apache2 \


--enable-so \
--enable-ssl \
--with-ldap \
--enable-ldap \
--enable-auth-ldap \
--disable-info \
--disable-status \
--disable-autoindex \
--disable-imap \
--disable-include \
--disable-userdir \
--disable-auth

checking for chosen layout... Apache


checking for working mkdir -p... yes
checking build system type... sparc64-unknown-linux-gnu
checking host system type... sparc64-unknown-linux-gnu
checking target system type... sparc64-unknown-linux-gnu

Configuring Apache Portable Runtime library ...


4.3 Compile the Apache server

Now that the software is validated and configured, it’s time to compile it. Since you won’t have a
compiler on your production host, we’ll compile and install it on a separate server, then
tar/compress it and scp it to your production host. You’ll need to run make using “sudo” so that
Apache knows it can use ports < 1000.

~> pwd
/usr/local/build/httpd-2.0.45

~> sudo make


===> src
make[1]: Entering directory `/usr/local/build/httpd-2.0.45'
make[2]: Entering directory `/usr/local/build/httpd-2.0.45/src'
===> src/regex
sh ./mkh -p regcomp.c >regcomp.ih

4.4 Install the Apache server


If you have followed our instructions for securing the host, you will have to unpack the
distribution and compile it on a separate host. To make your server more secure, use a
separate disk partition for your web content. Create a unique mount point for this directory
-- htdocs is a good name to use, but make it somewhere outside the ServerRoot directory.
You'll need to update /etc/vfstab to mount this partition as part of your server's startup
process.

Do not use the htdocs directory included in the distribution as your DocumentRoot. This directory
contains user documentation that you don't want to make available to the public as it contains

8 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

information a potential attacker could use to penetrate your system. (The attacker can deduce what
kind of web server you’re running, and hone his attack accordingly.) Move these documentation files
into your support directory so the webmasters for your site can refer to them as needed.

You’ll need to install the Apache server using “sudo” privileges or as root.

~> pwd
/usr/local/build/httpd-2.0.45

~> sudo make install


===> [mktree: Creating Apache installation tree]
./src/helpers/mkdir.sh /opt/apache2/bin
./src/helpers/mkdir.sh /opt/apache2/libexec
./src/helpers/mkdir.sh /opt/apache2/man/man1
./src/helpers/mkdir.sh /opt/apache2/man/man8
./src/helpers/mkdir.sh /opt/apache2/conf
..

5. Install SSL certificates


Now that the server is installed, we need to copy certificate key, server certificate, and CA chain to
Apache’s configuration directory.

5.1 Set up the Apache certificate directories

~> pwd
/opt/apache2/conf

~> sudo mkdir ssl.crt ssl.key

5.2 Copy the certificate and key to the SSL configuration directory

~> sudo cp /usr/local/build/server.crt ./ssl.crt/.


~> sudo cp /usr/local/build/server.key ./ssl.key/.

6. Configure the Apache server

Configure the file permissions and runtime settings of the Apache server. It’s important that you place your
htdocs, cgi-bin, and logs directories on separately mounted filesystems.

6.1 Configure httpd.conf

Set the following in your httpd.conf file. You can also download an example httpd.conf with
these settings here.

Directive and setting Description/rationale


ServerSignature Off Prevents server from giving
version info on error pages.
ServerTokens Prod Prevents server from giving
version info in HTTP
headers
Listen 80 (remove) Remove the “Listen”
directive – we’ll set this
directive only in ssl.conf,
so that it will only be
available over https.

9 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

User webserv (or whatever you created in Ensure that the child
step 2 above) processes run as
unprivileged user
Group webserv (or whatever you created in Ensure that the child
step 2 above) processes run as
unprivileged group
ErrorDocument 404 errors/404.html To further obfuscate the
ErrorDocument 500 errors/500.html web server and version,
etc. this will redirect to a page
that you should create,
rather than using the
default Apache pages.
ServerAdmin Use a mail alias – never use
<hostname>-webmaster@xianco.com a person’s email address
here.
UserDir disabled root Remove the UserDir line,
since we disabled this
module. If you do enable
user directories, you’ll
need this line to protect
root’s files.
<Directory /> Deny access to the root file
Order Deny, Allow system.
deny from all
</Directory>
<Directory /opt/apache2/htdocs"> LimitExcept prevents
<LimitExcept GET POST> TRACE from allowing
deny from all attackers to find a path
</LimitExcept> through cache or proxy
servers.
Options -FollowSymLinks -Includes
-Indexes -MultiViews
The “-“ before any
AllowOverride None
Order allow,deny directive disables that
Allow from all option.
</Directory>
FollowSymLinks allows a
user to navigate outside the
doc tree, and Indexes will
reveal the contents of any
directory in your doc tree.

Includes allows .shtml


pages, which use
server-side includes
(potentially allowing access
to the host). If you really
need SSI, use
IncludesNoExec instead.

AllowOverride None
will prevent developers
from overriding these
specifications in other parts
of the doc tree.

10 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

AddIcon (remove) Remove all references


IndexOptions (remove) to these directives,
AddDescription (remove) since we disabled the
ReadmeName (remove) fancy indexing
HeaderName (remove) module.
IndexIgnore (remove)
Alias /manual (remove) Don’t provide any
accessible references
to the Apache manual,
it gives attackers
too much info about
your server.

You should familiarize yourself with the following parameters. Unless you are running a high-volume
web site, you can safely leave the settings at their default values. If you are running a high-volume
web site, you’ll want to adjust these directives upward to better withstand denial-of-service
attacks.

StartServers
MinSpareServers
MaxSpareServers
Timeout
Keepalive
MaxKeepAliveRequests
KeepAliveTimeout
MaxClients
MaxRequestsPerChild

6.2 Configure ssl.conf

Set the following in your ssl.conf file. You can also download an example ssl.conf with these
settings here.

Directive and setting Description/rationale


SSLCertificateChainFile /opt/apache2 (Find this line and
/conf/ssl.crt/ca.crt uncomment it). This points
to the Certificate Authority
file for your chained
certificate.

6.3 Remove default Apache files

It’s important to remove default files such as .html files and CGI scripts (yes, even the Apache
manual). This will help obfuscate the server you’re running, targetted attacks against your web
server. You’ll probably want to build a simple index.html page to place in the htdocs directory, just so
you know the web server is working when you start it.

~> sudo rm –fr /opt/apache2/htdocs/*


~> sudo rm –fr /opt/apache2/cgi-bin/*
~> sudo rm –fr /opt/apache2/icons

To test that your web server is running, you can now place this file in your htdocs directory – it’s just
a simple index.html file. Make sure you set the permissions to world-readable.

6.4 Set directory and file permissions for the server

To protect the directories on your server, it’s important that you protect the directories themselves.

bin is where the executable portion of the Apache web server is. It should be

11 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

readable/executable only by members of the webadmin group, but only writable by root.

~> sudo chown –R root:webadmin /opt/apache2/bin


~> sudo chmod –R 770 /opt/apache2/bin

conf is where your web server configuration files are and needs to be read/writable only by the
webadmin group.

~> sudo chown –R root:webadmin /opt/apache2/conf


~> sudo chmod –R 770 /opt/apache2/conf

logs is where your access and error logs will go. It should be readable only by the webadmin
group.

~> sudo chown –R root:webadmin /opt/apache2/logs


~> sudo chmod –R 755 /opt/apache2/logs

htdocs is where your HTML files are and needs to be world readable, but writable only by root
(you should copy content in from a staging server).

~> sudo chown –R root /opt/apache2/htdocs


~> sudo chmod –R 775 /opt/apache2/htdocs

cgi-bin is where your executable scripts are and needs to be world read/executable, but
writable only by root (you should copy content in from a staging server).

~> sudo chown –R root /opt/apache2/cgi-bin


~> sudo chmod –R 775 /opt/apache2/cgi-bin

7. Make final configuration and start server


Lastly, we need to modify the startup configuration for Apache and restart the server.

7.1 Modify Apache startup script so that it will notify you when it’s restarted.

As a failsafe measure, you should notify your webmaster alias any time this server is restarted. That
way, you’ll be notified of any unauthorized attempt.

Open /opt/apache/bin/apachectl and add something like this to the file:

tail /opt/apache2/logs/error_log |
/bin/mail -s 'Apache web server has restarted'
<hostname>-webmaster@xianco.com

7.2 Test your configuration by starting the server

sudo /opt/apache2/bin/apachectl startssl

7.3 Keep your web server patched

Check web sites for Apache and all modules regularly and apply important patches.

Apache web server: http://nagoya.apache.org/dist/httpd/patches/

OpenSSL: http://www.openssl.org/source

OpenLDAP: http://www.openldap.org/

12 of 13 03/06/2013 15:16
Apache 2.0 Hardening Guide http://xianshield.org/guides/apache2.0guide.html

8. Configure authentication against an LDAP directory.

In this final section, we’ll configure the Apache httpd.conf file so that resources are authenticated against
an LDAP server. This step really can’t be run until you’ve installed the web server. Once you’ve got your
web server installed, just add the LDAP authentication directives to any directory (or httpd.conf file) where
you want password protection with CEC credentials. Here’s an example of protecting a directory named
“Internal”

<Location "/internal">
AuthName CEC
AuthType Basic
AuthLDAPURL ldap://ldap.xianco.com:389
/ou=employees,ou=people,o=xianco.com?uid?sub?(objectclass=xiancoPerson)
require valid-user
</Location>

13 of 13 03/06/2013 15:16

You might also like