Home » Apache, Debian, Featured, Headline, How-to, Php, Security

Apache Dynamic Virtual Hosting and PHP security

6 June 2011 6 Comments


It’s been a while since I configured the latest Dynamic Mass Virtual Hosting Server. Last time I used mod_vhost_alias to create a dynamic virtual hosting and it worked without any problem for what we need in that time. Then we didn’t care about the ftp and virtual users, the sites was updated from web pages and security was pretty much handled by upload application who managed the virtual hosting. Now, the problem is a little bit changed: We need a secure sever which should support ftp virtual users with quota and we don’t have permission to change the packages, apply patches or recompile sources, because we need to be able to upgrade without to much stress. I solved all problems related to ftp and virtual users, but we had a big challenge regarding Dynamic Virtual Hosting, PHP Security and Virtual Users.

First I tried to use suPHP with mod_vhost_alias, but first problem was virtual users. By default suPHP doesn’t support virtual users (should recompile the package), and even if it’s support virtual users you should configure a virtual host for each user … and this is not very easy to maintain and not very dynamic …

1
2
3
4
5
6
<VirtualHost *>
        suPHP_Engine on
        AddType application/x-httpd-phpx .phpx
        suPHP_AddHandler application/x-httpd-phpx
        suPHP_UserGroup #3001 #3001
</VirtualHost>

The second approach was to use mod_vhost_alias and php safe_mode and openbasedir for security … but no success, because openbasedir cannot get dynamic variables from apache for apache modules. This is the configuration what I tested:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NameVirtualHost *:80
UseCanonicalName Off
 
LogFormat "%V %h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"" dynamic_vhosts
CustomLog /data/logs/access.log dynamic_vhosts
 
<VirtualHost *:80>
    php_admin_value	safe_mode	on.
 
    <IfModule mod_vhost_alias.c>
      VirtualDocumentRoot /var/data/web/%0.0/htdocs
      VirtualScriptAlias /var/data/web/%0.0/cgi-bin
#      php_admin_value open_basedir VIRTUAL_DOCUMENT_ROOT
#       php_admin_value open_basedir /var/data/web/${lowercase:%{SERVER_NAME}}/htdocs
      php_admin_value open_basedir /var/data/web
    </IfModule>
 
</VirtualHost>


The best approach was with mod_macro. Is doing what I need, but it have one downside: you need to be very careful when you add a new virtual host.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<Macro vhost1 $sub $domain $admin>
    <VirtualHost your_ip_here:80>
           ServerAdmin $admin
           DocumentRoot "/var/data/web/$domain/htdocs/"
           ServerName $sub.$domain
           ServerAlias $domain
 
           <Directory "/var/data/web/$domain">
	      Options -Indexes FollowSymLinks MultiViews
	      AllowOverride All
	      Order allow,deny
	      Allow from all
      </Directory>
 
	  php_admin_value	safe_mode	on.
 
           php_admin_value open_basedir /var/data/web/$domain/
           CustomLog /var/data/logs/$sub.$domain-access.log combined
	   ErrorLog /var/data/logs/$sub.$domain-error.log
 
    </VirtualHost>
</Macro>.
 
<Macro vhost2 $sub $domain $admin>
    <VirtualHost your_ip_here:80>
           ServerAdmin $admin
           DocumentRoot "/var/data/web/$domain/htdocs/"
           ServerName $sub.$domain
 
           <Directory "/var/data/web/$domain">
	      Options -Indexes FollowSymLinks MultiViews
	      AllowOverride All
	      Order allow,deny
	      Allow from all
	  </Directory>
 
           php_admin_value	safe_mode	on.
           php_admin_value open_basedir /home/httpd/html/domains/$domain/
           CustomLog /var/data/logs/$sub.$domain-access.log combined
 
    </VirtualHost>
</Macro>
 
Include /etc/apache2/hosts.conf

and in /etc/apache2/hosts.conf


Use vhost1 www example1.com office@example1.com
Use vhost2 www example2.com office@example2.com
Use vhost2 www2 example2.com office@example2.com

The correct macro syntax is:

Use – mod macro directive
vhost1 – the name of macro
www – the hostname
example1.com – domain name
office@example1.com – the email for contact.

What is the difference between vhost1 and vhost2? Vhost1 uses ServerAlias and will make your domain to respond exactly as your host. For example calling http://example1.com will be the same as calling http://www.example1.com. vhost2 will configure just the host www.example2.com.

Splitting the configuration in multiple files has a an advantage: You can use it for other scripts, for example you can create/update awstats for the hosted websites.

Configure and install mod-macro under Debian is very easy:

# apt-get install libapache2-mod-macro
# a2enmod macro

and you are done.

For each configuration you need to reload the apache configuration:

# service apache2 reload

Good Luck!


6 Comments »

  • aufa said:

    I’m really still new to the website. I do not even know the basics of Apache. Maybe I should read the basic article about Apache

  • scipper said:

    hey, is it with the macro also necessary to add all vhosts in the /etc/hosts file?

  • admin (author) said:

    No

  • Mark said:

    Clean trick. Is this also possible with subdomains?

    i.e.

    Use vhost1 www example1.com webmaster@example1.com
    Use vhost2 sub example1.com webmaster@sub.example1.com

    Thanks in advance!

  • admin (author) said:

    yes, is working for subdomains!

  • raine ng said:

    I think the problem here is that you need to restart service. If you have a very busy site with hundreds of sub domain or domain this is not an easy task at all.

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.