Do, or do not. There is no ‘try’ |

Jul/07

29

Chrooting Apache2 howto

Credits and update log

This article was inspired by Artur Maj’s article Securing Apache: Step-by-Step. It shows in a step-by-step fashion how to install and configure the Apache 2.0.x series web server in much the same way as the 1.3.X covered in Artur’s article, i.e. “in order to mitigate or avoid successful break-in when new vulnerabilities in this software are found”.

Thanks to Davis Ford for pointing out that I forgot to mention the copying of the main httpd file to the chroot jail (minor omission…). It is mentioned now.

An update on December 16th 2004 included minor changes accomodating for a version upgrade to Apache 2.0.52 and some other adjustments in the httpd.conf file, which I had picked up along the way.

I have also found out that this article has been the basis of a subchapter in the book Apache Webserver 2 – Installation, Konfiguration, Programmierung by Sebastian Wolfgarten (Addison-Wesley 2004, ISBN: 3-8273-2118-2). For some reason the book claims that the original location of this text is at the cgisecurity.com site, which is obviously false, since the original location is naturally my home directory at the Computer Science department of the University of Helsinki (http://cs.helsinki.fi/u/janmatti/chrootapache2-howto.html).

Almost a year after my initial release of this article (October 14th 2003 – June 20th 2004), Artur Maj has released his own version entitled Securing Apache 2: Step-by-Step. Most of his examples are from FreeBSD, so if you’re running that, you might want to check his article out. The examples in this article are from Linux.

The June 15th 2005 update was for minor fixes to a couple of the code parts (e.g. replacing the deprecated use of chown with period as separator root.root to the correct syntax of root:root) and to accomodate for a version upgrade to Apache 2.0.54.

Another addition was the optional log rotation by adding the rotatelogs binary and modifying a couple of httpd.conf lines. This is optional, because rotatelogs runs as root, which is uncomfortable.

The latest update, May 9th 2006, includes minor changes accomodating for a version upgrade to the latest Apache 2.0.X, the 2.0.58 as well as removing unnecessary use of the root account from the build process and using sudo instead of the actual root account.

I’ve also noticed that my article features on a university course titled “IFT-22772 Securite dans les reseaux informatiques” at Université Laval of Quebec, Canada.

I’m (still) contemplating on writing a one-article guide for a HLFS based LAMP server, with https, as well as a howto for the newer Apache 2.2 series, but we’ll see how long it takes for me to actually get them done.
Introduction

Configuring your Apache2 server in accordance to the specifications laid out in this howto will result in limited functionality. The following will be available:

* Apache2 will be accessible from the Internet
* only static pages will be served (e.g. HTML or XHTML)
* name based virtual hosting
* specified web pages can be accessible only from selected IP addresses or users (basic .htaccess authentication)
* all web requests will be logged including information about the browsers

This howto does not cover such things as relational databases (MySQL, PostgreSQL, etc.), scripting languages (Python, Perl, PHP, Tcl, etc.), or any of a myriad of server side gadgets for interaction with web services. The reasons for this are beyond the scope of this howto, but involve security on multiple levels. For a better explanation to this and a number of other good security oriented observations, read Artur’s article.
Setup

The latest version of this howto has been built on Ubuntu 5.10 (Breezy Badger) with kernel 2.6.12-10-k7 running on i686 GNU/Linux.

The general idea of this howto should be portable to most Unixes. Some of the examples are specific to Linux.

The first step in securing any service is to close as many security holes in the operating system and then start closing holes in the service itself. This so called hardening of the OS is beyond the scope of this article, but there are some very good articles about the issue on e.g. the SecurityFocus site. So feel free to stop by there and come back later for the Apache2 part.
Installation and settings

Once all the other planned hardening has been executed we can begin the process of bolting up Apache2.

The first thing is to create a new username and usergroup to be used only by Apache2. Instead of using a name such as “apache2″, which potentially discloses information about the version of the Apache webserver, we should use a name like “apache” or “httpd” and create the new group and regular user like this (locking the group and passwd files usually requires root privileges, here this is accomplished with sudo, you may of course also use the root account):

sudo groupadd apache && \
sudo useradd apache -c “Apache2 server” -d /dev/null -g apache -s /bin/false

This sets the home directory to nada and gives no shell. Thus if the user account is compromised the cracker will have a slightly harder time obtaining a shell from which to launch any serious attack.

Also, by default, the Apache2 processes run with privileges of user nobody (except the main process, which runs with root privileges) and GID of group nogroup. If the account was compromised the intruder would gain access to all processes running under user nobody and group nogroup. Hence we run Apache2 under the UID/GID of a unique regular user/group, dedicated to Apache2.
Getting Apache2

Next you need to download the latest stable version of the Apache2 web server from your nearest mirror. Since some of the options of Apache2 can only be disabled during compilation, you need to download the source instead of a binary release. It is also good practice to always compile your own software, since then you’ll know what got put in and what got left out, right? You might argue, that to really know what got put in and what got left out, you would need to read and understand the code, and you would be right. For lesser gurus there is always an element of trust involved with using software developed by other people.

If you download the software from a mirror, be sure to verify the authenticity of the packages with GPG (or any OpenPGP compliant program) or MD5 as instructed at http://httpd.apache.org/dev/verification.html.

After downloading and verifying the packets, you need to unpack them. If you picked the smaller Bzip2′d archive, you can use

tar -xjvf httpd-2.0.58.tar.bz2

in your build directory.

Then you need to decide which modules are to remain enabled. All the modules available in the latest version of Apache 2.0.X (currently 2.0.58) can be found at http://httpd.apache.org/docs-2.0/mod.
Apache2 modules

The choice of modules is one of the most important steps in securing Apache2. The fewer you have, the better. In order to not incapacitate Apache2 completely and fulfill the functionality and security assumptions stated in the beginning, the following modules must remain enabled:
Module Description
core Core Apache HTTP Server features that are always available
http_core The core http support, required in every Apache installation
mod_access Provides access control based on client hostname, IP address, or other characteristics of the client request.
mod_auth User authentication using text files
mod_dir Provides for “trailing slash” redirects and serving directory index files
mod_log_config Logging of the requests made to the server
mod_mime Associates the requested filename’s extensions with the file’s behavior (handlers and filters) and content (mime-type, language, character set and encoding)

All of the aforementioned modules are installed by default, but a number of other modules are also installed by default. Since configure for Apache2 doesn’t support the –disable-all switch (like Apache 1.3.Xs configure) you need to disable the ones you don’t want and leave untouched the default ones you want. The following modules should thus be removed:

* mod_actions
* mod_alias
* mod_asis
* mod_autoindex
* mod_cgi
* mod_env
* mod_imap
* mod_include
* mod_negotiation
* mod_setenvif
* mod_so
* mod_status
* mod_userdir

This will leave you with the wanted modules listed before and use the default MPM, prefork.c.

Now, you may choose to include some more modules and change the MPM to suit your needs better. It is, however, worth to note that some Apache2 modules are more dangerous than others. For a discussion of these, please refer to the original Securing Apache: Step-by-Step article or any number of security related sites for example SecurityFocus.

The next issue is whether to compile the modules dynamically or statically. Static is better. If new vulnerabilities in Apache2 are found, you will probably have to recompile the whole thing anyway (because changes will most probably involve httpd, the main daemon) and by choosing the static method, you eliminate the need for one more module, mod_so.
Compiling Apache2

The latest distribution should have all necessary security patches included, but if for some reason it does not, you need to apply all these patches. After this, the server can be compiled as follows:

./configure –prefix=/opt/apache \
–disable-actions –disable-alias –disable-asis \
–disable-autoindex –disable-cgi –disable-env \
–disable-imap –disable-include –disable-negotiation \
–disable-setenvif –disable-so –disable-status \
–disable-userdir

The choice of prefix is naturally up to you, but I happen to use that one. It is a good idea to exclude all information about the version of apache in use, thus for example –prefix=/opt/apache-2.0.58 would be a bad choice.

After configure, run make, make sure the default access right settings for files and directories are proper, run make install as root and set the ownership for the new files and directories to UID/GID root.

make && \
umask 0022 && \
sudo make install && \
sudo chown -R root:root /opt/apache

The actual Chrooting of Apache2

The next phase is to limit Apache2’s access to the file system. This can be achieved by chrooting it’s main daemon, httpd. Chrooting means creating a new root directory structure. Thus when you move daemon files to it, and run the proper daemon in the new environment, it and all its child processes will have access only to the new directory structure.

As most of the following commands can only be run as root, now might be a good time to make yourself root.

su -

First you need to create the new root directory structure. I’ve done it under /chroot/httpd, you can choose whatever you like. To make the directory structure under /chroot/httpd, do this:

mkdir -p /chroot/httpd/{dev,etc,lib} && \
mkdir -p /chroot/httpd/opt/apache/{bin,logs,conf,lib} && \
mkdir -p /chroot/httpd/usr/{lib,libexec} && \
mkdir -p /chroot/httpd/usr/share/zoneinfo/Europe && \
mkdir -p /chroot/httpd/var/run && \
mkdir -p /chroot/httpd/web/vhosts

Naturally you’d want to put the zoneinfo, that’s relevant for you. The owner of all these directories should be root and the access rights should be set to 0755. Next you create the special device file, /dev/null and set its access rights:

mknod /chroot/httpd/dev/null c 1 3 && \
chown root:root /chroot/httpd/dev/null && \
chmod 666 /chroot/httpd/dev/null

Note: for FreeBSD systems this would be:

mknod /chroot/httpd/dev/null c 2 2
chown root:root /chroot/httpd/dev/null
chmod 666 /chroot/httpd/dev/null

Also a log device must be created under the chroot jail. This can be achieved by adding the lines (the comment is naturally optional)

#log device for chrooted Apache2
syslogd_flags=”-l chroot/httpd/dev/log”

to the /etc/syslog.conf file and restarting the syslogd daemon.

kill -HUP `cat /var/run/syslogd.pid`

If you don’t have the pid file in that directory, you can just check the running processes with ps aux and kill -HUP the one with COMMAND syslogd.

Note: for FreeBSD systems you would need to change the /etc/rc.conf file.

After these comes the time consuming part. You need to check each and every program and library for dependencies. I used ldd to begin with and strace to get all the rest. You should get something like this, when you ldd the main daemon, httpd (YMMV):

ldd /opt/apache/bin/httpd
linux-gate.so.1 => (0xffffe000)
libaprutil-0.so.0 => /opt/apache/lib/libaprutil-0.so.0 (0xb7fcb000)
libexpat.so.1 => /usr/lib/libexpat.so.1 (0xb7f9d000)
libapr-0.so.0 => /opt/apache/lib/libapr-0.so.0 (0xb7f7c000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f73000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7f50000)
libcrypt.so.1 => /lib/tls/i686/cmov/libcrypt.so.1 (0xb7f21000)
libnsl.so.1 => /lib/tls/i686/cmov/libnsl.so.1 (0xb7f0b000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7ef8000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7ef4000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dc6000)
/lib/ld-linux.so.2 (0xb7fe1000)

If you then run ldd for each of these files (linux-gate.so.1 is not a file, it’s a virtual DSO, see http://www.trilithium.com/johan/2005/08/linux-gate/ for further explanation), you should get something resembling this (YMMV):

ldd /opt/apache/lib/libaprutil-0.so.0
linux-gate.so.1 => (0xffffe000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7f25000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7df7000)
/lib/ld-linux.so.2 (0×80000000)

ldd /usr/lib/libexpat.so.1
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7ddd000)
/lib/ld-linux.so.2 (0×80000000)

ldd /opt/apache/lib/libapr-0.so.0
linux-gate.so.1 => (0xffffe000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f21000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7efe000)
libcrypt.so.1 => /lib/tls/i686/cmov/libcrypt.so.1 (0xb7ed0000)
libnsl.so.1 => /lib/tls/i686/cmov/libnsl.so.1 (0xb7eba000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7ea6000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7ea2000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d74000)
/lib/ld-linux.so.2 (0×80000000)

ldd /lib/tls/i686/cmov/librt.so.1
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e37000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7e24000)
/lib/ld-linux.so.2 (0×80000000)

ldd /lib/tls/i686/cmov/libm.so.6
/lib/ld-linux.so.2 (0×80000000)
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7df6000)

ldd /lib/tls/i686/cmov/libcrypt.so.1
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dd6000)
/lib/ld-linux.so.2 (0×80000000)

ldd /lib/tls/i686/cmov/libnsl.so.1
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e5a000)
/lib/ld-linux.so.2 (0×80000000)

ldd /lib/tls/i686/cmov/libpthread.so.0
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dd3000)
/lib/ld-linux.so.2 (0×80000000)

ldd /lib/tls/i686/cmov/libdl.so.2
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dc6000)
/lib/ld-linux.so.2 (0×80000000)

ldd /lib/tls/i686/cmov/libc.so.6
/lib/ld-linux.so.2 (0×80000000)
linux-gate.so.1 => (0xffffe000)

ldd /lib/ld-linux.so.2
statically linked

You then strace the httpd into a file and grep that for the word “open” and you should get out something like this:

strace -o /opt/httpd-trace /opt/apache/bin/httpd && \
grep open /opt/httpd-trace

Syntax error on line 367 of /opt/apache/conf/httpd.conf:
Invalid command ‘UserDir’, perhaps mis-spelled or defined by a module not included in the server configuration
open(“/opt/apache/lib/tls/i686/cmov/libaprutil-0.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/opt/apache/lib/tls/i686/libaprutil-0.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/opt/apache/lib/tls/cmov/libaprutil-0.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/opt/apache/lib/tls/libaprutil-0.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/opt/apache/lib/i686/cmov/libaprutil-0.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/opt/apache/lib/i686/libaprutil-0.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/opt/apache/lib/cmov/libaprutil-0.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/opt/apache/lib/libaprutil-0.so.0″, O_RDONLY) = 3
open(“/opt/apache/lib/libexpat.so.1″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/etc/ld.so.cache”, O_RDONLY) = 3
open(“/usr/lib/libexpat.so.1″, O_RDONLY) = 3
open(“/opt/apache/lib/libapr-0.so.0″, O_RDONLY) = 3
open(“/opt/apache/lib/librt.so.1″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/librt.so.1″, O_RDONLY) = 3
open(“/opt/apache/lib/libm.so.6″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libm.so.6″, O_RDONLY) = 3
open(“/opt/apache/lib/libcrypt.so.1″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libcrypt.so.1″, O_RDONLY) = 3
open(“/opt/apache/lib/libnsl.so.1″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libnsl.so.1″, O_RDONLY) = 3
open(“/opt/apache/lib/libpthread.so.0″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libpthread.so.0″, O_RDONLY) = 3
open(“/opt/apache/lib/libdl.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libdl.so.2″, O_RDONLY) = 3
open(“/opt/apache/lib/libc.so.6″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libc.so.6″, O_RDONLY) = 3
open(“/opt/apache/conf/httpd.conf”, O_RDONLY) = 3
open(“/etc/nsswitch.conf”, O_RDONLY) = 4
open(“/opt/apache/lib/libnss_compat.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/etc/ld.so.cache”, O_RDONLY) = 4
open(“/lib/tls/i686/cmov/libnss_compat.so.2″, O_RDONLY) = 4
open(“/opt/apache/lib/libnss_nis.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/etc/ld.so.cache”, O_RDONLY) = 4
open(“/lib/tls/i686/cmov/libnss_nis.so.2″, O_RDONLY) = 4
open(“/opt/apache/lib/libnss_files.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libnss_files.so.2″, O_RDONLY) = 4
open(“/etc/passwd”, O_RDONLY) = 4

Note: If you don’t have the user nobody, you’ll get the error httpd: bad user name nobody. You can avoid this by already changing the user and group in /opt/apache/conf/httpd.conf to apache. There’s an example httpd.conf file at the end of this article, which you can already use, just make sure you have the appriopriate directory structure ready or Apache2 will not start (it used to die silently, but there’s been some improvement to the code to get some feedback). The above has been done without modifying the httpd.conf, thus it complains about missing module UserDir (we disabled that feature).

The reason why we strace the httpd is that you need to copy each of these open files to the chroot jail with the exception of the /etc/ld.so.cache, which is created at runtime.

As you can see from the output of the httpd strace the daemon systematically starts checking for the libraries from its own lib/ directory (with the exclusion of the libaprutil-0.so.0 file). Thus you can copy all of the libraries directly to the /chroot/httpd/opt/apache/lib directory. Note that the ld-linux.so.2 file needs to be in /lib/ of the chroot.

Moving along, moving along. You copy the libraries to the chroot jail and put them in the opt/apache/lib/ and lib/ directories.

cp /opt/apache/lib/libaprutil-0.so.0 /chroot/httpd/opt/apache/lib/ && \
cp /usr/lib/libexpat.so.1 /chroot/httpd/opt/apache/lib/ && \
cp /opt/apache/lib/libapr-0.so.0 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/librt.so.1 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libm.so.6 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libcrypt.so.1 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libnsl.so.1 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libpthread.so.0 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libdl.so.2 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libc.so.6 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libnss_compat.so.2 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libnss_nis.so.2 /chroot/httpd/opt/apache/lib/ && \
cp /lib/tls/i686/cmov/libnss_files.so.2 /chroot/httpd/opt/apache/lib/ && \
cp /lib/ld-linux.so.2 /chroot/httpd/lib/

The next step is to copy the rest of the files mentioned in the strace:

cp /opt/apache/conf/httpd.conf /chroot/httpd/opt/apache/conf/ && \
cp /etc/nsswitch.conf /chroot/httpd/etc/ && \
cp /etc/passwd /chroot/httpd/etc/ && \
cp /etc/group /chroot/httpd/etc/ && \
cp /etc/resolv.conf /chroot/httpd/etc/ && \
cp /etc/host.conf /chroot/httpd/etc/ && \
cp /etc/hosts /chroot/httpd/etc/ && \
cp /opt/apache/conf/mime.types /chroot/httpd/opt/apache/conf/

And then create some necessary log files

touch /chroot/httpd/opt/apache/logs/error_log && \
touch /chroot/httpd/opt/apache/logs/access_log

The resolv.conf, host.conf and hosts files are optional and Apache2 will run without them. They are however useful, so you should find out what they are used for and include them in the chroot jail. Also, you need to remove all other lines from the passwd and group file except apache.

Note: If you copy paste the above commands and you don’t have for example a /etc/host.conf file, the copying will end there, so make sure that you separately copy paste the rest of the lines, if one of the commands gives you an error message.

Also remember to create the directory structure for the log files of your virtual hosts or the httpd will die silently. For a directory structure similar to the httpd.conf file at the end of this article you would do:

mkdir /chroot/httpd/opt/apache/logs/kakkonen.org

You might also wan to copy your timezone file to the chroot jail altough the httpd deamon will work without it. Using the timezone file will make your logs easier to read. To copy the timezone file to the chroot jail do:

cp /usr/share/zoneinfo/Europe/Helsinki /chroot/httpd/usr/share/zoneinfo/Europe/

Obviously you want to use the zoneinfo, that’s correct for you time zone. I just happen to live in Helsinki.
Testing

Now it’s time to see if the bugger works. Copy the main httpd daemon and one of the index files from /opt/apache/htdocs/ to the chroot jail:

cp /opt/apache/bin/httpd /chroot/httpd/opt/apache/bin/ && \
cp /opt/apache/htdocs/index.html.en /chroot/httpd/web/index.html

Change your /chroot/httpd/opt/apache/conf/httpd.conf to point to it. You can change only the DocumentRoot variable to /web and user and group to apache as well as commenting the UserDir, Alias, AliasMatch, ScirptAlias, IndexOptions, AddIconByEncoding, AddIconByType, AddIcon, DefaultIcon, ReadmeName, HeaderName, IndexIgnore, LanguagePriority, ForceLanguagePriority, and BrowserMatch lines for testing. Or you can just use the demo httpd.conf file at the end of this article, if that’s less tedious.

Then try to run Apache2 in the chroot jail (it will whine about all the misconfigured stuff, so just keep editing until you get it running):

/usr/sbin/chroot /chroot/httpd/ /opt/apache/bin/httpd

If everything works, your should be able to see a page with some Apache greeting text and no images if you point your browser to http://localhost. If you do see the welcome page, you can remove the build files and the original installation directory.

If Apache2 won’t work, try to strace the httpd again and grep the file for ENOENT (something not found).

You can also try to increase the level of Apache2’s logging by changing the LogLevel in the httpd.conf to debug.
Optional log rotation

I’ve found that the ability to search logs quickly is a Good Thing. Thus I’m including rotatelogs from the Apache2 bin/ directory to this howto as an optional extra. It requires minimal additional work, only copying the rotatelogs binary to the bin/ of the chroot jail and a minor modification to the httpd.conf file.

Obviously this increases the number of binaries running in the chroot jail by 100% and rotatelogs runs as root, which is uncomfortable, but on some systems the ability to rotate logs is worth the discomfort.

rotatelogs uses the exact same libs as httpd, so you don’t need to worry about adding any extra stuff into the jail. Just copy the rotatelogs binary:

cp /opt/apache/bin/rotatelogs /chroot/httpd/opt/apache/bin/

And comment/uncomment the ErrorLog and CustomLog lines in the httpd.conf at the end of this article according to whether you will or will not use the rotatelogs option.
Tuning

Fine tuning the httpd.conf is an art form, but you can get started with something like this:

# =================================================
# Basic settings
# =================================================
ServerRoot /opt/apache
ServerName bonobo
PidFile logs/httpd.pid
ScoreBoardFile logs/httpd.scoreboard

# =================================================
# Performance settings
# =================================================
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0

# =================================================
# General settings
# =================================================
Listen 0.0.0.0:80
User apache
Group apache
UseCanonicalName Off
ServerSignature Off
HostnameLookups Off
ServerTokens Prod
DirectoryIndex index.html
DocumentRoot /web/vhosts

# =================================================
# Access control
# =================================================

Options None
AllowOverride None
Order deny,allow
Deny from all


Order allow,deny
Allow from all

AccessFileName .htaccess

Order deny,allow
Deny from all

# =================================================
# MIME encoding
# =================================================
TypesConfig conf/mime.types
DefaultType text/plain

AddEncoding x-compress Z
AddEncoding x-gzip gz tgz
AddType application/x-tar .tgz

# =================================================
# Logs
# =================================================
LogLevel warn
LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\”" combined
LogFormat “%h %l %u %t \”%r\” %>s %b” common
LogFormat “%{Referer}i -> %U” referer
LogFormat “%{User-agent}i” agent
#without rotatelogs
#ErrorLog /opt/apache/logs/error_log
#CustomLog /opt/apache/logs/access_log combined
#with rotatelogs rotating weekly
ErrorLog “|/opt/apache/bin/rotatelogs /opt/apache/Dlogs/error_log.%Y-%m-%d 604800″
CustomLog “|/opt/apache/bin/rotatelogs /opt/apache/logs/access_log.%Y-%m-%d 604800″ combined

# =================================================
# Virtual hosts
# =================================================
NameVirtualHost 0.0.0.0:80

DocumentRoot /web/vhosts/kakkonen.org
ServerAlias kakkonen.org
ServerAdmin webmaster@kakkonen.org
#without rotatelogs
#ErrorLog /opt/apache/logs/kakkonen.org/error_log
#CustomLog /opt/apache/logs/kakkonen.org/access_log combined
#with rotatelogs rotating weekly
ErrorLog “|/opt/apache/bin/rotatelogs /opt/apache/logs/kakkonen.org/error_log.%Y-%m-%d 604800″
CustomLog “|/opt/apache/bin/rotatelogs /opt/apache/logs/kakkonen.org/access_log.%Y-%m-%d 604800″ combined

Source from http://www.cs.helsinki.fi/u/janmatti/chrootapache2-howto.html

No tags

No comments yet.

Leave a Reply

You must be logged in to post a comment.

<<

>>

Designed by devolux