Apache Chroot Jail: Virtual Hosting

by on December 22, 2008 · 23 comments· LAST UPDATED June 15, 2009

in , ,

Now your chrooted Apache jail is ready. It is time to add domains using Apache virtual hosting features.

Our sample setup for two domains called theos.in and nixcraft.com is as follows:

  • Domain: nixcraft.com
  • JailDir ($J): /httpdjail
  • Domain configuration file: /etc/httpd/conf/vdomains/nixcraft.com.conf
  • DocumentRoot: $J/home/httpd/.nixcraft.com/http
  • Log Directory: $J/home/httpd/.nixcraft.com/logs

Virtualhosting settings for theos.in:

  • Domain: theos.in
  • JailDir ($J): /httpdjail
  • Domain configuration file: /etc/httpd/conf/vdomains/theos.in.conf
  • DocumentRoot: $J/home/httpd/.theos.in/http
  • Log Directory: $J/home/httpd/.theos.in/logs

Step #1: Create SKEL directory for our jail

Type the following command:
# mkdir /etc/httpd.skel
# mkdir /etc/httpd.skel/{http,logs,stats,subdomains,private}

Update httpd.conf for virtual hosting

Create /etc/httpd/vdomains directory, type:
# mkdir /etc/httpd/vdomains
Open httpd.conf file, enter:
# vi /etc/httpd/conf/httpd.conf
Make sure following line exists. Use name-based virtual hosting:

NameVirtualHost *:80

At the bottom of file add the following directive:

include vdomains/*.conf

Save and close the file.

Step #1a: Add user for nixcraft.com domain

Type the following commands:
# J=/httpdjail
# useradd -m -d $J/home/httpd/.nixcraft.com -k /etc/httpd.skel -s /sbin/nologin nixcraft
# chmod +x $J/home/httpd/.nixcraft.com

Step #1b: Add user for theos.in domain

Type the following commands:
# J=/httpdjail
# useradd -m -d $J/home/httpd/.theos.in -k /etc/httpd.skel -s /sbin/nologin theos
# chmod +x $J/home/httpd/.theos.in

Virtual hosting configuration for nixcraft.com

Create /etc/httpd/vdomains/nixcraft.com.conf file as follows:

<VirtualHost *:80>
    ServerAdmin webmaster@nixcraft.com
    DocumentRoot "/home/httpd/.nixcraft.com/http"
    ServerName nixcraft.com
    ServerAlias www.nixcraft.com
    ErrorLog "/home/httpd/.nixcraft.com/logs/error_log"
    CustomLog "/home/httpd/.nixcraft.com/logs/access_log" common
    ScriptAlias /cgi-bin/ "/home/httpd/.nixcraft.com/cgi-bin/"
 
<Directory "/home/httpd/.nixcraft.com/http">
        Options -Indexes FollowSymLinks +ExecCGI
        AllowOverride AuthConfig FileInfo
        DirectoryIndex index.php index.html
        Order allow,deny
        Allow from all
</Directory>
 
<Directory "/home/httpd/.nixcraft.com/cgi-bin">
	AllowOverride None
	Options None
	Order allow,deny
	Allow from all
</Directory>
</VirtualHost>
 

Save and close the file.

Virtual hosting configuration for theos.in

/etc/httpd/vdomains/theos.in.conf

<VirtualHost *:80>
    ServerAdmin webmaster@theos.in
    DocumentRoot "/home/httpd/.theos.in/http"
    ServerName theos.in
    ServerAlias www.theos.in
    ErrorLog "/home/httpd/.theos.in/logs/error_log"
    CustomLog "/home/httpd/.theos.in/logs/access_log" common
    ScriptAlias /cgi-bin/ "/home/httpd/.theos.in/cgi-bin/"
 
<Directory "/home/httpd/.theos.in/http">
        Options -Indexes FollowSymLinks +ExecCGI
        AllowOverride AuthConfig FileInfo
        DirectoryIndex index.php index.html
        Order allow,deny
        Allow from all
</Directory>
 
<Directory "/home/httpd/.theos.in/cgi-bin">
	AllowOverride None
	Options None
	Order allow,deny
	Allow from all
</Directory>
</VirtualHost>

Save and close the file. Restart httpd, enter:
# /etc/init.d/httpd restart
You can automate the entire process using a shell or perl script which is left as an exercise to the reader.

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 23 comments… read them below or add one }

1 Janam March 23, 2009 at 7:24 am

Hello, I followed your tutorial in chrooting Apache and creating Virtual domains. However I have a problem. When I try accessing my website via the URL: http://mydomain.com/

I’m getting an error as indicated below:

“You don’t have permission to access / on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.”

What could I have not done correctly? This seems to be a common problem with new Linux installations such as mine but I have failed to find a solution that matches my case.

Reply

2 nixCraft March 23, 2009 at 9:23 am
3 Janam March 23, 2009 at 2:39 pm

Thanks for the page. I had not seen it. Btw 1 question on the virtualhost config files shown above. Why doesn’t the path to the DocumentRoot not begin from the jail directory. I.e Why do we use “/home/httpd/.nixcraft.com/http” in the config file and not “httpdjail/home/httpd/.nixcraft.com/http” ?
Thanks.

Reply

4 nixCraft March 23, 2009 at 3:07 pm

/ or /httpdjail is not accessible from the jail. Your /httpdjail becomes a new / directory and protects real / file system. So you need to use home/httpd/.nixcraft.com/http as path.

Reply

5 Janam March 23, 2009 at 4:49 pm

Hi,

I see. Then I can now understand why do not include httpdjail. Thanks alot.

I have tried to follow the above instructions to the letter but I get the following on console when I restart httpd:

Starting httpd: Warning: DocumentRoot [/home/httpd/.nixcraft.com/http] does not exist

Then viewing the error log, I also found this:
No such file or directory: httpd: could not open error log file /home/httpd/nixcraft.com/logs/error_log. Unable to open logs

So it occurs to me that Apache attempts to read the DocumentRoot before it gets chrooted into the jail or something like that? Could these two pieces of information be pointing at some configuration problem?

Reply

6 Janam March 24, 2009 at 6:24 am

Hello,

I finally got Apache to start up and everything works but I had to do change the logs directory and do a symlink to it. I think this is not yet a good solution enough but at least Apache starts and works fine. I am still combing this issue and I hope I shall share my solution once I am convinced I have one good enough.

Reply

7 Jeroen March 24, 2009 at 6:35 pm

Hello,

I had the same issues. After changing the log directories to the real path (/httpdjail/home/httpd/.theos.in/logs/*_log) it starts up buth with the warning that the directory /home/httpd/.theos.in does not exist. After that it works like a charm. Do we just have to ignore this warning, or is something not working as it should? I am using CentOS 5.2.

Reply

8 willi June 14, 2009 at 10:32 pm

Hello,
thank you for this howto.
A few things to say:
Please alter the Path in:
Virtual hosting configuration for nixcraft.com
Create /etc/httpd/conf/vdomains/nixcraft.com.conf file as follows:
should be /etc/httpd/vdomains/nixcraft.com.conf
———-
so far I got it qithout errors /chroot is built and mod_chroot says it is happy chrooting.
BUT the virtual domains path with /home… will not be reckoned by httpd.
SELinux is off but auditd is on.

Though I assume I’am not chrooted! Test with chroot without vdomains result in /var/www/html calls but not in {chroot}/var/www/html.

Thank you for your help.

Reply

9 nixCraft June 15, 2009 at 5:33 am

@willi,

Thanks for the heads up. I’ve update tutorial. Let me know if you need any other help.

Reply

10 willi June 15, 2009 at 5:43 am

well yes my main problem is:

from last posting:
so far I got it qithout errors /chroot is built and mod_chroot says it is happy chrooting.
BUT the virtual domains path with /home… will not be reckoned by httpd.

thank youi

Reply

11 xinobit June 30, 2009 at 12:53 am

But this doesn’t prevent a php script from reading a file in another virtualhost just by browsing the path. Is any solution for that? I mean a chroot for every virtualhost

Reply

12 nixCraft June 30, 2009 at 4:00 am

You can chroot each jail or better use suexec which prevents reading other users files by UID.

Reply

13 Milan Cveetic October 18, 2009 at 1:26 pm

apachectl -t

Warning: DocumentRoot [/home/httpd/.nixcraft.com/http] does not exist
Warning: DocumentRoot [/home/httpd/.theos.in/http] does not exist
Syntax OK

I did everything as written, do not know what the problem is

Reply

14 Arpad March 17, 2010 at 2:49 pm

Hi, thanks for the tutorial.
I’ve checked and overchecked everything. The settings are the same except from the chroot jail name. I have the same problem as others, it can’t seem to find the directories from the virtualhosts. If i use it without the virtualhost it starts normally and chroots the directory to /var/www/html (the chrooted not the real one). Where could be the problem?

Reply

15 Hal Wong May 18, 2010 at 8:01 am

This configuration did not work for me either however, I was able to get Virtual Hosting working by using the using the VirtualDocumentRoot directive instead. It works successfully inside the httpdjail.

Here’s how to do it. If you have applied the above instructions and it didn’t work then you should do the following:

Edit the Apache conf file:
vi /etc/httpd/conf/httpd.conf

First, comment out the NameVirtualHost:
#NameVirtualHost *:80

And comment out the vdomain directory lookup:
#include vdomains/*.conf

Then add (or uncomment) the following:
VirtualDocumentRoot /home/www/%0/
VirtualScriptAlias /home/www/%0/cgi-bin/

Then Save and Exit.

Now make the directories for all/any virtual hosts that you want:
mkdir /httpdjail/home/www/www.example.com

And give it the proper permissions
chmod +x /httpdjail/home/www/www.example.com

Then restart Apache:
/etc/init.d/httpd restart

If it comes up OK, then it should work. Test it out by placing an index.html in that new VirtualDocumentRoot directory that you just created and see if you can pull it up in a web browser. Keep in mind that you need to have the DNS entry already resolving to the box (OR you can modify your HOSTS file on your local system to manually direct to the webserver you are working on. More info: http://en.wikipedia.org/wiki/Hosts_file).

If everything works then you can delete the /etc/httpd/vdomain directory, and the /etc/httpd.skel directory, and also the /home/httpd/.nixcraft.com and also remove the new users you created from /etc/passwd and back out all the changes from this page.

Hope this helps.

Reply

16 drake February 25, 2011 at 6:45 pm

hi it works:)

Tell me sth:
1. how can users access to chroot e.g to sent their own index.html (users dont exist in os)
2. only access to chroot, got a root

I Think, I don’t undrestand sth in that chroot…
regards,
drake

Reply

17 pron August 25, 2010 at 9:10 pm

tryed several manuals for chroot, but i always get next error :

Warning: date(): It is not safe to rely on the system’s timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected ‘Europe/Berlin’ for ‘CEST/2.0/DST’ instead in /var/www/html/index.php on line 6 Fatal error: date(): Timezone database is corrupt – this should *never* happen! in /var/www/html/index.php on line 6

it’s on fedora 13.

again – always if i try to integrate mod_chroot, i get that error.

if i “turn off” mod_chroot, i do have no problem.

what could be the cause?

Reply

18 Hal Wong August 26, 2010 at 7:30 am

You need to make a copy the zoneinfo files into your jail so php can read them and understand the definition of all the timezones and internationalization settings.

if your jail is in /httpdjail, just do this:

cp -fR /usr/share/zoneinfo/* /httpdjail/usr/share/zoneinfo/

Reply

19 Janhouse January 9, 2011 at 3:25 pm

Thank you!
Took some time for me to find this comment. I knew that I had to copy something to jail but didn’t know what. :)

Reply

20 A.Jesin September 27, 2010 at 4:20 pm

Is there a PHP script available to add/edit/remove apache virtual host through the browser ?

Reply

21 bill March 22, 2011 at 8:23 am

hi guys .. this looks like an ok solution but does anyone know how to do this with the mod_chroot now included with apache2 since .10 release? it seems to me that the mod_chroot allows all of one directory to be in a jail but does not prevent virtual hosts from intruding into each other.

Reply

22 Mato March 1, 2012 at 4:51 am

I have the same problem as Milan and Arpad. Followed the previous instructions and these, but apachectl -t or restarting apache tells me that the /home/httpd/.mydomain.com/http does not exist. I also get errors in the global apache error log that the vhost logs file does not exist. Using Centos 5.7 with apache 2.2.3 and have turned selinux off temporarily. Hope someone has some advice.

Reply

23 inlink August 8, 2012 at 4:34 pm

you can use mpm_itk. This isolates different virtual hosts from each other.

Reply

Leave a Comment

Tagged as: , , , , , , , , , , , , , , , , ,

Previous post:

Next post: