KBTAG: kben10000130
URL: http://www.securityportal.com/lskb/10000100/kben10000130.html
Date created: 07/08/2000
Date modified: 10/06/2000
Date removed:
Authors(s): Kurt Seifried seifried@securityportal.com
Topic: Apache webserver
Keywords: Network/WWW
What can I say about securing Apache? Not much actually. By default Apache runs as the user 'nobody', giving it very little access to the system, and by and large the Apache team has done an excellent job of avoiding buffer overflows/etc. In general most www servers simply retrieve data off of the system and send it out, most of the danger come not from Apache but from sloppy programs that are executed via Apache (CGI's, server side includes, etc).
If going with Apache, I would recommend using the 1.3 series unless you have some strange requirement for sticking to 1.2, the active development is now on 1.3, and includes many new features from security, usability, stability and performance viewpoints. Most servers based upon Apache (Red Hat Secure Server, Stronghold, etc.) are generally just as bug free but there are occasionally problems. You can download Apache from http://www.apache.org/. Almost all distributions ship with it, so you should have it as package or whatever.
Making Apache "stealthy"
It might be desirable in some situations to make Apache "stealthy". Most web servers can be trivially identified by issuing a command such as "HEAD / HTTP/1.0":
TTP/1.1 200 OK Date: Sat, 07 Oct 2000 03:33:19 GMT Server: Apache/1.3.12 (Unix) mod_ssl/2.6.2 OpenSSL/0.9.5 Last-Modified: Sun, 25 Jun 2000 08:33:38 GMT ETag: "2bd64-158-3955c3e2" Accept-Ranges: bytes Content-Length: 344 Connection: close Content-Type: text/html
Or by using Netcrafts's website: http://www.netcraft.co.uk/.
To deal with this there are two directives that control how much information Apache gives out, ServerTokens and ServerSignature. Funnily enough ServerTokens only supports "Prod" in version 1.3.12, so if a webserver replies with:
Server: Apache
then you know it is 1.3.12 (at least as long as 1.3.12 is the latest version). All other commands, "Min", "OS" and "Full" show the version of Apache. The other alternative is to edit the source code and recompile it. Information on ServerTokens and ServerSignature is available at:
http://www.apache.org/docs/mod/core.html#servertokens
http://www.apache.org/docs/mod/core.html#serversignature
User directory permissions
A common problem is making /~username/ available, yet having secure user directory permissions. Many modern distributions such as Red Hat Linux do not make user directories world readable by default. This means that Apache (which runs as "nobody" typically) is not able to traverse into the /home/username/public_html directory. To make this work simply set /home world readable and executable, and /home/username world executable. The directory /home/username/public_html then needs to be world readable and executable. Being world executable means anyone can cd into the directory, however unless it is world readable they cannot see the contents of the directory.
drwxr-xr-x 11 root root 4096 Aug 9 23:13 home drwx-----x 9 username username 4096 Oct 2 19:55 /home/username drwx---r-x 9 username username 4096 Oct 2 19:55 /home/username/public_html
Chroot'ing Apache
If you want to be paranoid I would suggest running Apache in a chrooted environment, this however is sometimes more trouble then it is worth. Doing this will break a great many things. You must also install numerous libraries, Perl, and any other utilities that your Apache server will be using, as well as any configuration files you wish to have access to. Any CGI scripts and other things that interact with the system will be somewhat problematic and generally harder to troubleshoot.
The simplest way to setup Apache chrooted is to simply install it and move/edit the necessary files. A good idea is to create a directory (such as /chroot/apache/), preferably on a separate filesystem from /, /usr, /etc (hard links, accidental filling of partitions, etc...), and then create a file structure under it for Apache. The following is an example, simply replace /chroot/apache/ with your choice. You must of course execute these steps as root for it to work. RPM supports this with the --root /some/dir directive, simply install Apache and the needed libs using rpm (thus gaining it's support for dependencies/etc, making your life easier). If you are not on an RPM based system simply use ldd to find out which shared libraries are required, and move everything needed into your /chroot/apache/ directory.
[seifried@host seifried]$ ldd /usr/bin/httpd libm.so.6 => /lib/libm.so.6 (0x40017000) libc.so.6 => /lib/libc.so.6 (0x40060000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Apache logs requests and so forth internally, so you don't have to worry about setting up pseudo logging daemons like holelogd to pass information to syslog in order to get your log files behaving.
About the simplest way to secure Apache and insure that it doesn't have unnecessary access to your filesystem is to create a /www/ or similar directory and place ALL the websites, web content, cgi's and so forth under it. Then you can simply set access.conf up to deny any access to /, and enable access to /www/ and its various cgi-bin directories.
Example for httpd.conf:
<Directory /> Options None AllowOverride None </Directory>
<Directory /www > Options Indexes FollowSymLinks Includes AllowOverride None </Directory>
Controlling access
Access to directories can also be controlled easily, Apache supports the defining and placement of files (usually referred to as htaccess files) that can control access based on username and password, IP of origin, and so forth. This is defined in srm.conf:
AccessFileName .htaccess
The format of this file is covered in the Apache documentation, and is identical to directives you would place in access.conf (well almost). User authentication via username and password is also covered in depth at: http://www.apacheweek.com/features/userauth.
If you also want to prevent people from viewing the .htaccess file(s), place this in your srm.conf:
<Files .htaccess> order allow,deny deny from all </Files>
This will disallow the viewing of any file called '.htaccess'.
This is the one I currently use (simple because I tried it before Apache with mod_ssl, and it worked). You need to get Open-SSL, compile and install that, and then patch Apache with the Apache-SSL patch, compile Apache, and off you go. Open-SSL is available from: http://www.openssl.org/, simply get the latest tarball, unpack it, and run:
./config make make test make install
It hasn't ever failed for me yet. You then need get the Apache-SSL stuff from http://www.apache-ssl.org/, unpack the Apache source somewhere, cd into the top level dir (/usr/local/src/apache_1.3.9/) and then unpack the Apache-SSL stuff into it (it tells you to do this in the docs, sort of a catch 22). You then simply run:
./FixPatch
Which should work (if it doesn't read the README.SSL), then configure Apache as usual, and run make, followed by make install. Skip down to the "Creating a certificate" section.
Apache with mod_ssl is available from http://www.modssl.org/. I haven't tested it yet.
Creating a certificate
This is the easy part, the next step is to create a key set, and then configure httpsd.conf to use it appropriately. Find where "openssl" is installed and make sure it is in your path, then cd to wherever you placed your apache config files (whatever you prefixed as the apache root followed by /conf/). If you need to create a test certificate, simply to use internally then you can:
openssl genrsa -des3 > httpsd.key openssl req -new -x509 -key httpsd.key > httpsd.crt
Browsers will complain loudly about this certificate because it is created by the person who signs it, and they are untrusted. If you want to generate a certificate, and a certificate request to send to someone like Thawte or Verisign then you need to:
openssl genrsa -des3 > httpsd.key openssl req -new -key httpsd.key > httpsd.csr
You can also get real certificates with limited life times (usually a week or two) from Verisign to use for testing in a more "real world" environment.
Configuring Apache for SSL
There are several things you will need to add to your Apache config file to get Apache with SSL extensions actually doing anything useful with your certificates. You'll need to add some global configuration settings (note these apply to 1.3.9, and will barf on earlier versions of Apache):
# you will need to tell apache to listen to port 443, by default it only goes for 80 Listen 443 # if you use more then one secure site on an IP (BAD IDEA) you will need: NameVirtualHost 10.1.1.1:443 #it's a good idea to disable SSL globally and enable it on a per host basis SSLDisable # SSL cache server, without this your server will die SSLCacheServerPath /usr/bin/gcache # port the cache server runs on SSLCacheServerPort 12345 # timeout for the SSL cache, set shorter for testing, 300 is a good "real world" value SSLSessionCacheTimeout 300
Now you can create a virtual host with SSL enabled:
<VirtualHost www.example.com:443> DocumentRoot /www/secure/ ServerName www.example.com ServerAdmin example@example.com ErrorLog logs/https_error.log TransferLog logs/https_access.log # enable SSL for this virtual host SSLEnable # this forbids access except when SSL is in use. Very handy for defending # against configuration errors that expose stuff that should be protected SSLRequireSSL SSLCertificateFile /usr/conf/httpsd.crt # if the key is not combined with the certificate, use this # directive to point at the key file. [OPTIONAL] SSLCertificateKeyFile /usr/conf/httpsd.key # If you want to require users to have a certificate you will need a bundle of # root certificates so you can verify their personal certificates #SSLCACertificateFile /etc/ssl/ca-cert-bundle.pem SSLVerifyClient none </VirtualHost>
apache-userdirldap
apache-userdirldap allows you to use an LDAP directory for looking up user home directories. In other words if you want to move all your users into an LDAP directory and do ALL authentication through it, you won't have to break Apache. You can get it at: http://horde.net/~jwm/software/apache-userdirldap/.
References: