How To Set Up Mass Virtual Hosting With Apache2 + Mod - Rewrite + Mod - Userdir + Mod - Suexec On CentOS 5
How To Set Up Mass Virtual Hosting With Apache2 + Mod - Rewrite + Mod - Userdir + Mod - Suexec On CentOS 5
Before we start
For illustration purposes, I'm assuming that www.example.com exists and points to the
our web server IP 192.168.1.1. The webroot for example.com is located in
/home/vhosts/example.com/public_html.
Apache2
Install Apache:
vim /etc/httpd/conf/httpd.conf
## splittable logs
LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon
RewriteEngine On
##-----------------------------------
## where hostname has www prefix
##-----------------------------------
## Firstly create custom variable that contains the host without the
www prefix
RewriteCond %{HTTP_HOST} ^www\.(.*)$
RewriteRule .? - [E=noWWWHost:%1]
##-----------------------------------
## where hostname *does not* have www prefix
##-----------------------------------
## Map the virtualhost to the documentroot
RewriteCond %{REQUEST_URI} !^/~
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^/(.*)$
/home/vhosts/${lowercase:%{HTTP_HOST}}/public_html/$1
Our websites are located in /home/vhosts - each subfolder is the domain name of
the website (without the www prefix) e.g. /home/vhosts/example.com.
If a request hits the server for www.example.com it will be dynamically re-written
to example.com.
The documentroot directory is 'public_html' - this name is required by suEXEC as
we'll see later. If you don't intend to use suEXEC then you make this whatever
you like & update the rewriterule accordingly.
/etc/init.d/httpd start
tail /var/log/httpd/error_log
As this is a shared web hosting platform, with many different users & websites we want
to execute CGI scripts as the owner of the website rather than as the webserver process.
suEXEC allows us to do this a) statically using virtualhost config or b) dynamically using
mod_userdir.
Firstly, each website must be owned by a user with the same name as the website's
domain name. For example website example.com:
You could either add each user manually to /etc/passwd or set up your host to look up an
LDAP directory for account information.
Enable mod_userdir:
vim /etc/httpd/conf/httpd.conf
<IfModule mod_userdir.c>
UserDir public_html
</IfModule>
Now when we request a page from the webserver using the form
http://192.168.1.1/~example.com Apache will look in the home directory for username
example.com for the public_html directory. This by itself isn't very useful as we don't
want people to have to use the ~/ bit in their URLs. Instead we will silently rewrite the
URL from www.example.com to http://192.168.1.1/~example.com behind the scenes.
This particular rewrite doesn't need to be done for every page - only for CGI scripts that
we want to run under suEXEC. Other pages will get handled by the earlier re-write rules.
Edit /etc/httpd/conf/httpd.conf. Below the existing rewrite rules, insert the following:
<Directory /home/vhosts/*/public_html>
AddHandler cgi-script .pl .cgi
Options +ExecCGI
</Directory>
/etc/init.d/httpd reload
Create the Perl script test.pl in the virtual host's public_html with the following contents:
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "<H1>test.pl Hello World</H1>\n";
Give the script executable permissions & change ownership to the correct user:
chmod +x test.pl
tail /var/log/httpd/error_log
tail /var/log/httpd/suexec.log
PHP + Python
Extending suEXEC processing to include PHP & Python (or anything else) is simple.
First, make sure php-cli and python packages and their dependencies are installed:
test.py
#!/usr/bin/python
test.php
#!/usr/bin/php-cgi
<?
echo "test.php Hello world!";
?>
Chown the files to be owned by the correct user, and set the executable bit with chmod
+x.
Note: each script needs to have the interpreter specified on the first line e.g.
#!/usr/bin/python. To avoid having to do this with each file, you can do the following:
Now modify Apache config to rewrite requests for files with .php and .py extensions. We
also need to add these extensions to the handler for cgi-script
/etc/httpd/conf/httpd.conf
<Directory /home/vhosts/*/public_html>
AddHandler cgi-script .pl .cgi .php .py
Options +ExecCGI
</Directory>
tail /var/log/httpd/error_log
tail /var/log/httpd/suexec.log
Catchall
If you'd like to direct requests for non-existent virtual hosts to one catchall site, make this
your last rewrite rule in /etc/httpd/conf/httpd.conf: