The challenge with securing a shared hosting server is how to secure the website from attack both from the outside and from the inside. PHP has built-in features to help, but ultimately it s the wrong place to address the problem. Apache has built-in features too, but the performance cost of these features is prohibitive.

This has created a gap that a number of third-party solutions have attempted to fill. One of the oldest of these is suphp, created by Sebastian Marsching. How well does it work, and how well does it perform?

  • suphp: Running PHP As A Specified User
  • Installing suphp
  • Configuring Apache
  • Some Benchmarks
  • Other Considerations
  • Conclusions

suphp: Running PHP As A Specified User

Like Apache’s own suexec, suphp is a solution that allows PHP to run as the user and group that owns any particular website on a shared hosting server.

suphp consists of two components:

  • mod_suphp, an Apache module that replaces mod_php
  • suphp, a setuid binary that replaces Apache’s suexec

It relies on PHP/CGI having been installed onto the server first.

Installing suphp

suphp is compiled and installed in the same way as any other Apache module. These instructions are for Apache 2.2, but they will work fine for Apache 2.0 as well. (You can run suphp on Apache 1.3 too). (Gentoo Linux and Seed Linux users can skip these instructions; you can install suphp using ‘emerge mod_suphp‘).

Download the suphp source code from the website. Unpack the tarball somewhere, like this:

tar -zxf suphp-0.6.2.tar.gz
cd suphp-0.6.2

Next, run the configure script:

./configure --with-setid-mode=paranoid 
    --with-min-uid=1000 
    --with-min-gid=100 
    --with-apache-user=www 
    --with-logfile=/var/log/apache2/suphp_log 
    --with-apxs=/usr/sbin/apxs 
    --with-apr=/usr/bin/apr_config

You’ll need to adjust some of these settings to suit your local operating system:

  • –with-min-uid sets the lowest user id that PHP is allowed to run as. Check your /etc/passwd file to see just how low this needs to be set.
  • –with-min-gid sets the lowest group id that PHP is allowed to run as. Check your /etc/group file to see just how low this needs to be set.
  • –with-apache-user tells suphp which user Apache will be running as.
  • –with-logfile tells suphp where to write log messages to. I recommend that you configure suphp to write its logfile in the same directory that Apache would normally write its log files.
  • –with-apxs tells suphp where to find the Apache util that’s used to help build Apache modules.
  • –with-apr tells suphp where to find the Apache Portable Runtime (apr) config util.

It’s worth pointing out that there are several different options to choose from for the –with-setid-mode config. Check out the suphp documentation (included in the source tarball) for the details on what each mode does.

Next, run make to compile the software.

Assuming everything compiles just fine, the next step is to install mod_suphp by copying it to your Apache modules directory:

cp  src/apache2/.libs/mod_suphp.so /usr/lib/apache2/modules/

After that, you need to install the suphp binary:

cp src/suphp /usr/sbin/suphp
chmod 4755 /usr/sbin/suphp

mod_suphp is hard-coded to expect the suphp binary to be installed into /usr/sbin. If you put it anywhere else, mod_suphp won’t be able to run PHP for you!

To finish, download the suphp configuration file from Gentoo’s CVS, and install it as /etc/suphp.conf. Then, edit the file, updating all the settings to match the values you passed to the configure script.

Configuring Apache

The first thing you need to do to your Apache config files is to comment out mod_php. mod_suphp is a replacement for mod_php; you cannot run both at the same time.

Then, in your main httpd.conf file, add the following:

LoadModule suphp_module modules/mod_suphp.so
AddType application/x-httpd-php   .php
AddHandler application/x-httpd-php .php

suPHP_Engine On

<Location />
SuPHP_AddHandler x-httpd-php
</Location>

DirectoryIndex index.php index.htm index.html default.htm default.html

This tells Apache to load mod_suphp, to associate it with PHP scripts, and to look for index.php et al when a URL only specifies a folder name instead of a file.

The final step is to go into each of your virtual hosts, and tell mod_suphp which user owns the virtual host. This will the user and group that PHP will run as.

<VirtualHost www.example.com>
SuPHP_UserGroup stuart mybusiness
</VirtualHost>

Now you’re ready to restart Apache and to run some tests to make sure that suphp is up and running.

Some Benchmarks

suphp works the same way as Apache’s suexec. Every time a PHP script is run, suphp has to fork Apache and then execute another copy of the PHP/CGI binary. This approach provides the absolute security benefits that we seek, but is much slower than using mod_php.

To benchmark suphp, I used Apache’s ab benchmark to load a simple phpinfo() page 1,000 times. I ran the benchmark five times, and averaged the results.

  • suphp: average of 164.677 seconds
  • mod_php: average of 6.422 seconds

suphp is some 25 times slower than mod_php. This is a substantial performance hit, but it’s better than suexec, which benchmarked at 36 times slower than mod_php. I admit to being surprised that suphp performs better than suexec; I plan to put all of the alternatives covered here in a “head to head” article soon!

Other Considerations

One neat feature of suphp is that it can support both PHP 4 and PHP 5 running on the same box at the same time. Hopefully, you’ve already made the move to PHP 5 and you don’t need this feature – but it’s there if you do.

The same feature can be used to support both PHP 5 and PHP 6 (when it’s released) at the same time.

Be aware that the last release of suphp was in 2006. There is an active mailing list you can join for community help and support.

Conclusions

suphp is an easy-to-install, easy-to-configure and easy-to-maintain alternative to Apache’s own suexec. If you are running a shared server and the horrific performance penalty doesn’t put you off, then suphp is well worth looking at instead of using suexec.

But the question is – is there anything better out there, something that provides both security and performance? In the next article, I’ll take a look at a third-party Apache mod that attempts to answer that.

This article is part of The Web Platform, an on-going series of blog posts about the environment that you need to create and nurture to run your web-based application in. If you have any topics that you d like to see covered in future articles, please leave them in the comments on this page.

26 Comments

  1. Jan Schneider says:
    January 18th, 2008 at 9:39 am

    I don’t think the benchmarks you run give a good impression about the performance impact. phpinfo() isn’t really an expensive operation. I expect the PHP initialization taking most of the time in your tests, and that’s of course more expensive with suexec or suphp.
    With some real world application benchmarks, I would expect the difference becoming smaller. It’s probably still a magnitude, and the additional CPU and memory resources can’t be denied. But the tradeoff that admins have to consider when implementing such a protection is much different whether your users’ script run 25-35 times slower compared to say 5-10 times.
    I don’t know if the difference would really get that “small”, but I would really be interested in benchmarks better matching real world applications.

  2. Mats Lindh says:
    January 18th, 2008 at 10:53 am

    I would also recommend checking out apache2-mpm-itk which is available through debian-repositories and as a source code patch at http://mpm-itk.sesse.net/ . This patch also allows you to run different virtualhosts as different users, and does not limit itself to only PHP.

  3. Stu says:
    January 18th, 2008 at 12:53 pm

    @Jan: That’s a fair point. Once I’ve finished reviewing the main options for shared hosting, I’ll put together a better set of benchmarks as a ‘head to head’ article.

    @Mats: I’m planning to look at mpm-peruser next, and then mpm-itk in the article after that. ITK is interesting from a performance point of view, but the security problems it brings need careful consideration :(

  4. developercast.com » Stuart Herbert’s Blog: Using suphp To Secure A Shared Server says:
    January 18th, 2008 at 2:56 pm

    [...] Herbert has posted about a very helpful method server admins can use out there to not only help secure their server but [...]

  5. Lee says:
    January 20th, 2008 at 2:06 am

    I’ve tried using suphp and suexec in the past with Apache, and after all the performance problems I decided to my to the Lite Speed web server. It gives me the performance and security I want for a very reasonable cost.

  6. Using mpm-peruser To Secure A Shared Server | Stuart Herbert On PHP says:
    March 20th, 2008 at 5:35 pm

    [...] fast as mpm-prefork (the traditional way of running mod_php) in this simplistic test, and it leaves suphp and suexec trailing in the [...]

  7. Noel says:
    April 5th, 2008 at 3:54 pm

    Have you also considered options like FastCGI in combination with mod_fcgid for example?

  8. Stuart Herbert says:
    April 5th, 2008 at 5:42 pm

    @Lee: There hasn’t been much interest in LiteSpeed when I’ve asked for feedback, to be honest. But I will look at it. Thanks!

    @Noel: I haven’t considered FastCGI so far. The problem I perceive with FastCGI is that it’s designed to have persistent CGI processes running between page views. If you have hundreds or more sites on a single server, you’ll need a lot of extra RAM to keep the FastCGI processes running all the time.

    I will look at it though. I think it would be good to try and cover as many options as possible (even if only to rule them out) so that the advice is comprehensive.

  9. alfeze says:
    April 12th, 2008 at 8:00 pm

    this was a very well written article – thank you!

    I have been contemplating for some time and will be going with suphp however I wanted to know the effects it would have on my current customers….is it seamless transition or will clients be effected?

    cheers

  10. Stuart Herbert On PHP - » Using mpm-itk To Secure A Shared Server says:
    April 19th, 2008 at 1:01 pm

    [...] benchmarks much better than suexec and suphp, but is still quite a bit slower than [...]

  11. Phill Brown says:
    July 9th, 2008 at 3:59 pm

    Are there any disadvantages to suPHP compared to suExec other than performance difference Stuart?

    Cheers,
    Phill

  12. Fwolf’s Blog » Blog Archive ??????????php?????? - Fwolf's Blog says:
    July 13th, 2008 at 10:47 am

    [...] Using suphp To Secure A Shared Server????????????????????? [...]

  13. Run PHP scripts with different users on the same server « PHP::Impact ( [str Blog] ) says:
    August 10th, 2008 at 8:11 pm

    [...] Herbert wrote a nice article explaining how to secure a shared server using suPHP: The challenge with securing a shared hosting [...]

  14. geetha says:
    August 27th, 2008 at 5:31 am

    I think so suPHP might be little slower tham mod_php

  15. Stuart Herbert On PHP - » Can You Secure A Shared Server With PHP + FastCGI? says:
    December 7th, 2008 at 4:51 pm

    [...] The belief is that using FastCGI will overcome the performance issues of Apache’s suexec or mod_suphp, because FastCGI processes persist between page [...]

  16. Perry says:
    January 12th, 2009 at 9:10 am

    Keep in mind, if you transition to suPHP on production systems, you’ll want to remove all old session data (which will be owned by the previous owner of the httpd process).

    i.e. rm -f /tmp/sess_*

    Files in the existing users home directories may need to have some ownership/permissions changed as well. suPHP doesn’t like world/group writable files by default.

    Finally, once you have secured your users directories from each other, ensure the users root directory has a group owner of the httpd process (nobody or apache), and that all website content files are group/world readable beyond the users parent directory. This will ensure httpd can read static html content as well as run php scripts as the user safely.

  17. Aaron says:
    March 13th, 2009 at 2:31 am

    This stuff is a bitch to get working.

  18. Something Interactive » Guide: Web-based control of X10 Home Automation (CM15A) on Ubuntu Linux0n says:
    May 7th, 2009 at 10:08 pm

    [...] implemented properly, and why not use some other PHP method like suPHP. The problem is that suPHP is known to take a huge performance hit on the system being up to 25 percent slower. The [...]

  19. Jon says:
    May 14th, 2009 at 1:51 am

    I have a whole server to myself, it has Plesk 8.6 and CentOS. I was looking into suPHP because all the ownerships Plesk? makes for the files are bad for running CMS like Joomla. Infact it doesn’t run.

    I am going to try your method above, and see if I can get it to work.

    If it doesn’t work, do you think Cpanel would be more friendly with Joomla out of the box?

  20. Valics Lehel says:
    November 12th, 2009 at 6:47 am

    We are using suphp on all of our servers and so far noone complained about it is slower. Could be, but not that many times, maybe 1.2 or 1.6 based on our tests, but that can be ignored by the advantage offered.

  21. Gareth Bult says:
    January 26th, 2010 at 5:14 pm

    Hi Stuart .. long time no speak!

    We’re fairly heavily into WordPress hosting these days and I came across this article recently .. interesting! One thing the Apache solutions all have in common (apart from the apparent lack of performance..!) is that they’re a pain to get going. “suphp” for example on Ubuntu 9.10 seems (at least for me!) not to work – a number of documented issues.

    I notice you missed out mod_suid2 (I guess deliberately, but when one gets desperate it’s almost worth looking at anything), fyi Ubuntu’s stock apache isn’t built with HOLE enabled and even when you recompile from source results are not great.

    Anyway, just to approach this from a different angle, we’re playing with lighttpd as an alternative to Apache. Config (overall) is much lighter than Apache and setting up per-user permissions didn’t take me long at all.

    What’s a little scary is the performance I’m seeing .. either Apache is a complete dog or you’re running some really nasty hardware for testing .. ;-)

    This is what I get in a shared (virtual) server [single core] for a one-line php script that just calls phpinfo() as described [set up with per user permissions];

    Server Software: lighttpd/1.4.22
    Server Port: 80

    Document Path: /wp-hello.php
    Document Length: 50842 bytes

    Concurrency Level: 1
    Time taken for tests: 1.486 seconds
    Complete requests: 1000
    Failed requests: 0
    Write errors: 0
    Total transferred: 51026747 bytes
    HTML transferred: 50842000 bytes
    Requests per second: 673.01 [#/sec] (mean)
    Time per request: 1.486 [ms] (mean)
    Time per request: 1.486 [ms] (mean, across all concurrent requests)
    Transfer rate: 33536.61 [Kbytes/sec] received

    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 0.0 0 0
    Processing: 1 1 0.1 1 2
    Waiting: 1 1 0.1 1 2
    Total: 1 1 0.1 1 2

    Percentage of the requests served within a certain time (ms)
    50% 1
    66% 1
    75% 1
    80% 1
    90% 2
    95% 2
    98% 2
    99% 2
    100% 2 (longest request)

    Hardware / OS;

    KVM instance, single core, 1Gb RAM, Ubuntu 9.10, AMD Phenon II X4 / 3.2
    (ab run from same instance, obviously .. :) )

  22. Zhicheng Wang says:
    September 9th, 2010 at 2:27 am

    if i use suphp on my server, can i still use applications such as xcache and memcached?

  23. Guide: Web-based control of X10 Home Automation (CM15A) on Ubuntu Linux « Something Interactive says:
    November 10th, 2010 at 10:30 pm

    [...] implemented properly, and why not use some other PHP method like suPHP. The problem is that suPHP is known to take a huge performance hit on the system being up to 25 percent slower. The [...]

  24. Bachsau says:
    May 22nd, 2011 at 1:46 pm

    mod_suphp is NOT a replacement for mod_php, just because of the name. It’s more a replacement for mod_cgi in conjunction with suexec.

  25. Hosting absichern: Apache2 mit ITK-MPM | martin-mueller.info says:
    July 2nd, 2011 at 10:41 pm

    [...] Herbert hat sich dankenswerter Weise schon vorher die Mühe gemacht, die 5 gängigsten Varianten (suphp, mpm-peruser, mpm-itk, PHP + FastCGI und suexec + PHP + FastCGI) einem Vergleich zu unterziehen. [...]

  26. sanu says:
    February 10th, 2012 at 3:20 am

    i configured suphp.but it is not interpreting php script. but it is just giving an option to download the file