User Tools

Site Tools


linuxtips:apacheconfig

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.

Scenario

  • One server, many users and one or more domains for each user.
  • The users should be able to use php-scripts for their webpages.
  • A user must not be able to access data from other users.
  • php-scripts should be able to use system tools so that applications like gallery or a CMS will work.

Problem

  • php scripts will be executed with privileges of the user apache is running as. This is bad because then every user can access the same data including the home directories of any user.

Possible solutions

mod_chroot

Ths apache module mod_chroot can be used to chroot() an apache process into a virtual hosts DocRoot.

Disadvantages:

  • system tools have to be copied into every chroot because the apache process can access nothing more that its own DocRoot.
    • This can mean much work for the admin.
    • It uses more diskspace
    • It will complicate TPE (trusted path execution) or makes it unpossible to use reducing system security
    • chrooting to a vhost only works with the Apache2 module

PHP safe_mode

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:

  • opening files owned by the user is not possible if apache is still running as a different user
  • using system wide php classes or libraries is not possible because they are not owned by the user
  • some php applications may not work anymore

suPHP

With suPHP/mod_suphp any php script is executed with uid of the owner of the script.

Disadvantages:

  • for every http request a new php-cgi process will be started through the suphp wrapper which will do set(e)uid()/set(e)gid() before serving the request. This makes it terrible slow. It will work for a page with a low number of hits, but high traffic webpages will be too slow and it will kill your webservers performance.

mod_become

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:

  • Slow as suPHP
  • Static html pages are slow, too
  • Apache must be recompiled with -DBIG_SECURITY_HOLE

Conclusion so far

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:

**The** solution?

mod_fastcgi

This module can be used to pre-fork cgi processed and let them running instead of starting up a new process for every request.

Apache2, php5-fcgi, php4-fcgi, mod_fastcgi HowTo (german)

Benchmarking

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

Preparation

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:

  • for static pages
NStatic HTML page
RGET /static/ HTTP/1.0
E<html><head><title>testpage</title></head><body>this is a test</body></html>
  • for php pages
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).

Apache plain or with mod_php4

Installation/configuration:

 aptitude install apache php4

Apache with php4-cgi

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.

Apache with suPHP

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

Apache with mod_become

Installation/configuration:

Apache with mod_fastcgi

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>

Apache2 with mod_fastcgi

TODO

Results

{| 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)

linuxtips/apacheconfig.txt · Last modified: 2012/01/14 05:13 by mschiff