Skip to content

HowTo Secure a php server for shared hosting environments – Part 1

by daimon on Mai 17th, 2010


Today, every Linux distribution is easily configured to serve php/mysql pages. Normally, an apache 2.2 server is installed with mod_php, which gives you the best performance and a relatively low memory footprint. This is great, if you run your own Server – but in a shared hosting environment, there are some serious security implications:

  • The php-scripts are run under the context of the apache user. Therefore, php scripts from one user have complete access to other user’s webroots (safe_mode is broken, open_basedir is deprecated).
  • Because of this, the apache user has to have complete read/write access to all webroots. If your apache becomes compromised, so are all your user’s webroots. That, in return, becomes much easier through all the exposed applications of your users (undoubtedly ridden with security holes), which aren’t under your control.
  • For your users to be able to upload/change their files via ftp _and_ the apache user to have complete write access, you either have to use virtual users for ftp and in fact grant the ftp user full access to all webroots (chroot environments can be broken!) – or you have to assign ridiculous umasks (e.g. 000).

So, how can we solve this problem? First, we have to assure that the php-scripts can only acces their own document roots. Also, they should not be able to expose the complete webserver through their security holes. The solution to this is an apache module named mod_suexec, which executes a cgi-script in it’s own dedicated user context. There’s just one problem left: With mod_php, the scripts are interpreted within the apache process, so there is no process to start for suexec.

There are a number of ways to deal with these implications. The old-fashioned way, to run php as a cgi-script, cures our security woes – but instantiates a new php process for every page request, which is instantly terminated after the request has been served. This is pretty bad performance-wise, to say the least. Especially on high-traffic sites, you can run into downtimes pretty easily.

But! this problem has also been solved long ago. The resolution to this is FastCGI, which also instantiates a process of the php executable – but just keeps it running after the script has finished. So for the next script, there’s already a php process waiting in the memory and execution happens nearly as fast as with mod_php. You just need a bit more memory for the instantiated php processes.

Also, our ftp problems have just gone away – every user owns his webroot, and only he has the permissions to read/write in his webroot (there’s one exception: the apache user still has to be able to read non-interpreted files like htmls, images and downloadable files). So ftp-wise you just login with that dedicated user account and voila – you have every permission you need (and not more!). Another noteworthy side-effect is that you can implement filesystem quotas easily now.

If you want to know more on the background (quite possibly easier to understand):

We have now built a cage for every customer on your shared hosting server, which can’t be easily broken out of. But what happens inside the cage? The applications still have their implicit vulnerabilities against common web attacks like SQL injection and XSS (cross-site scripting), which probably won’t harm you as easily as on a mod_php-server, but in combination with privilege-escalation type of attacks an intruder could still gain root access to your server. You can’t do anything about your customer’s faulty applications, can you?

In fact, you can. And you should! 70% of today’s network attacks are web-based – say, they exploit applications exposed via HTTP. That’s a layer above your old-fashioned IP exploits, and vastly more complex to manage. How do you reduce the risk to be hacked on the TCP/IP layer? Of course, the first thing to do is to put a firewall in front of the host at risk. You just reduce the operations possible on the host by blocking ports, source adresses and the frequency of possible actions on different services. But on the web application level, your traditional firewall will show it’s limitations. Thats because it doesn’t look into the content of the packets. You need another application to do that, and thats a Web Application Firewall or, more generally, an Intrusion Prevention System. The big open-source solution is called mod_security and plugs directly into apache. it checks every request against a set of rules (just like a traditional firewall) which decide if a request is legitimate or probably an attack.

The last point to mention (but probably the first to think about) is the Operating System to choose for secure hosting. This is more or less a matter of your personal preference. Probably you will use a GNU Operating System, which is ideal for apache/php webhosting. Personally, I love debian for its package management and easy updates (also fast security updates!) and it’s famous stability. If you like more current packages (but perhaps not as stable), ubuntu server is the way to go.

So this is the way i’ve chosen to go: debian stable + apache2.2 + suexec + fcgid + php + mod_security.

HowTo configure your (debian/ubuntu-based) host for secure shared hosting

In this HowTo, i just explain the major steps I’ve taken. Something may be amiss, just alert me about missing pieces and I will put them in.

1. Adjust sources.list

First, I adjusted the /etc/apt/sources.list of our host to include backported and non-free packages. I need the non-free backports for an up-to-date modsecurity package. Here’s what it looks like:

deb lenny main contrib non-free
deb-src lenny main contrib non-free

deb lenny/updates main contrib non-free
deb-src lenny/updates main contrib non-free

deb lenny/volatile main contrib non-free
deb-src lenny/volatile main contrib non-free

# Backports
deb lenny-backports main contrib non-free

of course, you have to adjust for your local/global mirror.

2. install necessary packages

# apt-get install php5-cgi apache2-mpm-worker apache2-suexec libapache2-mod-fcgid ssh proftpd quota quotatool pwgen mailx
# a2enmod suexec

You need the apache worker model to be able to use suexec. proftpd is great when using ftp quotas, and the quota/quotatool package limits filesystem usage block-based per user, to account for data generated by the webserver (e.g. files uploaded via HTTP). pwgen is used for automating the creation of users (the password generation part, obviously).

- To be continued – meanwhile, read about another way to configure your server here: (engl. translation)

No comments yet

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS