Security – How to chroot VirtualHosts on a Apache server

apache-2.2freebsdSecurityvirtualhost

I have a FreeBSD server (company's OS of choice). Currently we run several websites on each of the webservers. Websites are in PHP which is run in Apache Module mode. At the Apache is not chrooted so Apache and PHP have access to the whole filesystem.

For my private websites I use a shared hosting service. It seems that the service provider is running a customised Apache version. What is interesting, each website (VirtualHost I presume) on the server is chrooted the to DocumentRoot. How would I go about doing this on my Apache setup?

I have looked at Apache's ChrootDir which is almost good enough for me, but there is either a problem with it handling VirtualHosts or me not being able to set it up properly. Although it seems to run fine – can access VirtualHosts – there seems to be a problem when (re)starting the apache. I get warnings for VirtualHosts DocumentRoot. The config extract:

ChrootDir "/usr/local/www/apache22/data"
DocumentRoot "/"

<VirtualHost *:80>
    DocumentRoot "/test-1"
    ServerName test-1.example.com
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "/test-2"
    ServerName test-1.example.com
</VirtualHost>

And the warnings are:

Warning: DocumentRoot [/test-1] does not exist
Warning: DocumentRoot [/test-2] does not exist

Also, there are a lot more problems with SSL enabled. Haven't got round to resolving those yet though.

So, my questions are:

  1. How to chroot each VirtualHost to its DocumentRoot?
  2. How to properly chroot Apache's global DocumentRoot to make it work with VirtualHosts and SSL?

Best Answer

#1) Chrooting virtual hosts individually is not supported. The "Context" for the ChrootDir directive is "server config," and thus...

"This means that the directive may be used in the server configuration files (e.g., httpd.conf), but not within any <VirtualHost> or <Directory> containers. It is not allowed in .htaccess files at all." [1]

It is otherwise already working fine for you, albeit with annoying warnings which are easy to get rid of. Just...

cd / ; ln -s /usr/local/www/apache24/data .

...and then not only will the spurious and annoying warnings be gone, but you will have a nice, short and handy path to Apache's ChrootDir directory.

In my [yes, FreeBSD too] case, it was...

cd / ; ln -s /usr/local/www/apache24/data/vhosts .

...which I think is a little nicer, but to each his own.

#2) You are "chroot[ing] Apache's global DocumentRoot" here. As stated, that's all that is supported. Your /test-? directories will work as virtual hosts just fine if you finish configuring them with ServerName directives and whatever else you'd like. Same with SSL.

*) Regarding your provider, they could be doing all manner of things to achieve their isolation. No telling from here. Sorry.

*) Finally, since you are using PHP, you might also want to set "open_basedir" in your php.ini file to lock it down similarly as well. And note that this can be set individually for each virtual host by including something like the following in each virtual host's definition...

php_admin_value open_basedir "/data/test-1"

[1] http://httpd.apache.org/docs/2.4/mod/mod_unixd.html#chrootdir