To configure apache for a single domain is easy. To configure apache with multiple virtual hosts for a single webmaster is easy, too.
But if you need to host several domains for several different users this can be much more difficult. The biggest problem is to offer PHP functionality while keeping the system secure and fast.
Ths apache module mod_chroot can be used to chroot() an apache process into a virtual hosts DocRoot.
Disadvantages:
The PHP safe_mode may be used to tell PHP to not allow access to files not owned by the same user as the script itself, restrict several php functions such as system() exec() fopen() etc.
Disadvantages:
With suPHP/mod_suphp any php script is executed with uid of the owner of the script.
Disadvantages:
Using mod_become there is no need for suPHP anymore making it possible to use mod_php instead of php-cgi. It will setuid()/setgid() the apache process before serving a request.
Disadvantages:
If its secure and fast, it has limitations. If it is secure and has no limitations, its slow.
Now what? Impossible to do that? Wait. There might be another solution:
This module can be used to pre-fork cgi processed and let them running instead of starting up a new process for every request.
For testing we install apache and all other needed stuff into a default debian sarge chroot.
Hardware:
Intel(R) Celeron(R) CPU 2.00GHz with 512MB of RAM
We use a tool called hammerhead to stress our apache.
The tool httping will be used to test apache's response time
Benchmarking with hammerhead:
I tried to find a hammerhead config that will get most out of the webserver, but will not stress the hammering machine too much.
There are two different scenarios:
NStatic HTML page RGET /static/ HTTP/1.0 E<html><head><title>testpage</title></head><body>this is a test</body></html>
NDynamic page (PHP) RGET /php/ HTTP/1.0 E<html><head><title>testpage</title></head><body>this is a test</body></html>
The corresponding testpages will be created like that:
- cd /var/www/ /var/www# mkdir static php /var/www# echo "<html><head><title>testpage</title></head><body>this is a test</body></html>" > static/index.html /var/www# echo "<?php echo '<html><head><title>testpage</title></head><body>this is a test</body></html>'; ?>" > php/index.php /var/www#
Config will be the same for all tests:
Scenario_file ./scns/{static,php}.scn Log_filename /dev/null Report_Log /dev/stdout Load_images off Sessions 30 Sequence_probability 100 Sleep_time 20 Run_time 120 Machine_Name <webserver:port> Seed 123456789
This means 30 threads will hammer the webserver for two minutes. Each thread will wait 20 msec between requests.
Each test is run five times and the best result is taken (Avg. resp./sec).
Installation/configuration:
aptitude install apache php4
Installation/configuration:
aptitude install apache php4-cgi apache-modconf apache enable mod_actions
A file named php4-cgi is placed in /etc/apache/conf.d with the following content:
<IfModule mod_actions.c> <code> Action application/x-httpd-php /cgi-bin/php4
</IfModule> </code>
Restart apache.
Installation/configuration:
aptitude install apache suphp
A file named suphp is placed in /etc/apache/conf.d with the following content
suPHP_Engine on suPHP_ConfigPath /etc/php4/cgi/ AddType application/x-httpd-php .php AddHandler x-httpd-php .php
This enables the suPHP engine in a global context.
Restart apache.
suPHP will refuse to run scripts as user root. The following is done to be sure suPHP finds a smooth environment where it feels comfortable and will run our php testscript as another user.
adduser suphp-test [[...]] - cd /var/www/php/ /var/www/php# chown suphp-test:suphp-test . index.php /var/www/php# l total 12 drwxr-xr-x 2 suphp-test suphp-test 4096 2005-07-06 14:50 . drwxr-xr-x 4 root root 4096 2005-07-06 15:54 .. -rw-r--r-- 1 suphp-test suphp-test 94 2005-07-06 15:56 index.php /var/www/php#
To test the setup you can place a line like system(“touch foo”); into the test script and check that there is a file called foo after executing the script that is owned by user suphp-test
Installation/configuration:
Installation/configuration:
aptitude apache libapache-mod-fastcgi
Answer “yes” to the suEXEC question!
aptitude install libkrb53 libzzip-0-12 php4-cli php4-common
Install self build php4-cgi version with fastcgi enabled (needs -common and -cli, too):
dpkg -i php4-common_4.3.10-15.fastcgi.0_i386.deb dpkg -i php4-cgi_4.3.10-15.fastcgi.0_i386.deb dpkg -i php4-cli_4.3.10-15.fastcgi.0_i386.deb
Make aptitude not want to remove those packages:
aptitude unmarkauto php4-cgi
Enable mod_actions:
apache-modconf apache enable mod_actions
Add user fcgi-test
adduser fcgi-test
Now create the fast-cgi starter script:
vi /var/www/fcgi-bin/php-fcgi-starter
Content of /var/www/fcgi-bin/php-fcgi-starter:
- !/bin/sh PHPRC="/etc/php4/cgi/" export PHPRC PHP_FCGI_CHILDREN=4 export PHP_FCGI_CHILDREN exec /usr/lib/cgi-bin/php4
Filesystem structure for the vhost is as follows:
/var/www/ /var/www/htdocs /var/www/htdocs/static /var/www/htdocs/static/index.html /var/www/htdocs/php /var/www/htdocs/php/index.php /var/www/fcgi-bin /var/www/fcgi-bin/php-fcgi-starter
Set correct permissions:
- cd /var/www/ /var/www# chown fcgi-test:fcgi-test fgci-bin fcgi-bin/php-fcgi-starter htdocs/php htdocs/php/index.php /var/www# chmod 0755 php-fcgi-starter /var/www#
A new vhost is configured in a file /etc/apache/conf.d/test-vhost.conf:
NameVirtualHost *:10086 <VirtualHost *:10086> <code> ServerAdmin me@domain.de ServerName www.domain.de DocumentRoot /var/www/htdocs DirectoryIndex index.php index.html index.htm User fcgi-test Group fcgi-test <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www> Options FollowSymLinks AllowOverride AuthConfig Order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /var/www/fcgi-bin/ <Directory "/var/www/fcgi-bin"> AllowOverride None Options +ExecCGI -MultiViews -Indexes Order allow,deny Allow from all </Directory>
</VirtualHost> </code>
TODO
{| border=“1” cellpadding=“2”
! Config || Test 1-5 !! Best of 5 !! Average
! static
645/686/663/652/686 | 686 | ||
! mod_php
409/406/407/408/397 | 409 | ||
! php4-cgi
034/034/033/034/035 | 035 | ||
! suPHP
029/032/029/031/030 | 032 | ||
! mod_fastcgi/php4-cgi
388/391/386/370/384 | 391 | ||
{| border=“1” cellpadding=“2”
! Config / Results ! Test 1-5 !! Best of 5 !! Average
! static
807/823/835/842/808 | 842 | ||
! mod_php
425/423/420/414/423 | 425 | ||
{| border=“1” cellpadding=“2”
! Config / Results ! Test 1-5 !! Best of 5 !! Average
! mod_fastcgi/suexec/php-fcgi (dynamic server)
1.52/1.47/1.33/1.78/1.55 | 1.78 | ||
! mod_fastcgi/suexec/php-fcgi (static, 1 server)
238/252/164/236/265 | 265 | ||
! mod_fastcgi/suexec/php-fcgi (static, 2 servers)
247/246/257/264/275 | 275 | ||
! mod_fastcgi/suexec/php-fcgi (static, 3 servers)
269/233/258/230/242 | 269 | ||
! mod_fastcgi/suexec/php-fcgi (static, 4 servers)
260//// | |||
! mod_fastcgi/suexec/php-fcgi (static, 5 servers)
//// | |||
! mod_fastcgi/suexec/php-fcgi (static, 10 servers)
//// | |||
! mod_fastcgi/suexec/php-fcgi (static, 15 servers)
//// | |||
–mschiff 01:55, 12 Jul 2005 (CEST)