WordPress, suPHP, and Ubuntu Server 10.04

If you have WordPress running under an unprivileged user account, you may have noticed that when trying to install or delete a plugin that it prompts you for FTP information. This is due to a rather unintuitive way that WordPress checks for file access:

The following code is from the get_filesystem_method() method in the wp-admin/includes/file.php file:

if( function_exists('getmyuid') && function_exists('fileowner') ){
    $temp_file = wp_tempnam();
    if ( getmyuid() == fileowner($temp_file) )
        $method = 'direct';

This code creates a temporary file and confirms that the file just created is owned by the same user that owns the script currently being run. In the case of installing plugins, the script being run is wp-admin/plugin-install.php.

This may seem a little counter-intuitive, since the only thing WordPress really needs to be able to do is write to the wp-content/plugins directory.

If you’re on your own server (i.e. your own box or a VPS) and not worried about security implications, you can simply make the files owned by your web server process (usually www-data or nobody). This will have WordPress’ check succeed and no longer ask for your information.

If you’re on your own server and running a shared hosting environment, or just care about the security implications, you should install suPHP.

What are the security implications? If all web files are owned by the web server process, it’s extremely easy for someone to introduce malicious php code which can affect other sites on the server. Since the web server process has access to all of the web server files across the server, malicious code would have no problem gaining access to other files and directories on the server.

suPHP, configured correctly, causes all php scripts under a defined directory (usually /home) to run as the user account they are owned by. It also enforces other security measures, such as requiring that directories and files do not have write permissions for anyone other than the user.

I could go on and on about what it does, but my biggest struggle has been getting it to work. Installation is easy, but it’s painfully clear it does not work out of the box. After dozens of searches I found varying different ways of making it work, but sometimes drastic and not clean nor easy, few didn’t require recompiling something (which I wasn’t going to do), and none of them seemed to work.

After more than a day of searching and testing, I finally came up with a simple, elegant, working solution. Note that this was written and based on Ubuntu Server 10.04 64-bit, and libapache2-mod-suphp 0.7.1-1 and may or may not work for other platforms.

Install suPHP:

apt-get install suphp-common libapache2-mod-suphp

Edit the sites-enabled/xxxx.conf file for your VirtualHost

Inside your directive, add:

php_admin_flag engine off
AddHandler application/x-httpd-php .php .php3 .php4 .php5 .phtml
suPHP_AddHandler application/x-httpd-php
suPHP_Engine on

Lastly, edit /etc/suphp/suphp.conf and under ;Handler for php-scripts (at the bottom) change:




Restart apache and all should be well.

/etc/init.d/apache2 restart

Note: You might get an error message like the following:

Syntax error on line 7 of /etc/apache2/sites-enabled/
Invalid command 'php_admin_flag', perhaps misspelled or defined by a module not included in the server configuration

In this case, check that you actually have the Apache PHP mod installed and enabled. In can get uninstalled or disabled on occasion when upgrading Apache. Here’s how to reinstall/reenable:

sudo apt-get install libapache2-mod-php5
sudo a2enmod php5

Checking that it’s working

Create a phpinfo.php file with the follow contents:

<?php phpinfo(); ?>

Call it via your browser and check the Server API line near the top: CGI / FastCGI means suphp is working. Anything else means it’s not.

Suphp is slow!

Yes, unfortunately suphp is slow. Suphp runs PHP scripts in CGI mode, which reportedly causes them to run slower. I would argue that the security advantages outweigh the need for fast scripts, but each situation is unique. You have to decide for yourself.

500 Internal Server Error

If you’re getting the 500 Internal Server Error, it means that suphp is probably working, but for some reason it won’t allow the script to run.

Check that you don’t have any PHP opcode caching (APC, etc) running. If you are running any type of PHP opcode cache suphp will never work. You must disable your opcode caching. If you’re using APC, you can disable it system-wide by simply editing /etc/php5/conf.d/apc.ini and commenting the line out with a semicolon as follows:


Another element of importance is file permissions. SuPHP will fail (with a 500 Internal Server Error) any file that has permissions which are not allowed, as defined in /etc/suphp/suphp.conf. For example:

; Security options

Any file or directory with the attributes defined as allow=false will fail. Based on the configuration above, any file that is group- or world-writable will automatically fail. Same with directories. It’s best to leave these options alone (instead of changing them), and change the permissions on your scripts instead.

However, it is supposedly possible to disable it on a per-VirtualHost basis. I haven’t tested this.

Also check that your /var/log/suphp/suphp.log file isn’t over 2GB. If it is, rotate it or delete it.

If all else fails, check /var/log/suphp/suphp.log and /var/log/apache2/error.log for hints.

Many thanks to all of the blogs and articles that each held a piece of this puzzle. :)


, , , , , , , , ,