If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

HOWTO: PHP 5 CLI to PHP 5 CGI + suPHP

I recently decided to switch from using PHP CLI to CGI mode with suPHP. Here are the steps I followed to ensure everything was working. Let me know if you spot any flaws or know of a better way of doing this.

NOTE: I am continually updating this post. It is safe to assume that all posts which mention improvements/security fixes have been included where relevant if they were posted before the last time this post was edited. (See bottom of this post for timestamp)

Ok, lets get started..

suPHP doesn't allow the use of php_flag and php_value in .htaccess files, so find users with these setup and deal with them (or their sites will throw a 500 error)

If you need a custom config of PHP or suPHP then you can find which config files to change using:

Code:

./build used_configs

Now we can build PHP

Code:

./build php

Ensure the new php.ini is correct.. the old one was located at /usr/local/lib/php.ini

Code:

nano /usr/local/etc/php5/cgi/php.ini

It might be worth using custombuild to secure php some more. Using secure_php disables register_globals and adds some potentially vulnerable functions to the disable_functions list in the main php.ini file. These can be overridden on an individual basis per user if need be in their individual php.ini files

Code:

./build secure_php

We need to reset ownership of files as suPHP won't allow access to ones owned by apache (they way the CLI version of PHP works)

Now lets enable open_basedir per user, and create user's own tmp directories to make the server more secure. (I realize that I have done this on a per user basis rather than per domain, it should be straight forward to change if you do want it per domain)

automate creation of per user php.ini for new users (make sure the chown refers to your DirectAdmin user)

------------------------------------------------------------
Thanks to smtalk for some troubleshooting at http://www.directadmin.com/forum/showthread.php?t=19221
Thanks to getUP for securing the php.ini file
Thanks to Dennis for the suggestion of running ./build secure_php and cron job heads up
Thanks to scooby2 for suggesting extra openbase_dir paths e.g. php's pear modules
Thanks to jlasman for spotting a typo

Also, please keep in mind that php-cgi much slower than mod_php.
Next, you should define openbasedir php setting, otherwise users will be able to browse your server (about comparatively their unix permissions).
Opcode cachers (something like eaccelerator, xcache, apc) can't work in this mode too.

If you completely switch to php-cgi (suphp) you should comment out "loadmodule ... php5_module" in your httpd.conf (for reduce memory usage per httpd child)

Also, please keep in mind that php-cgi much slower than mod_php.
Next, you should define openbasedir php setting, otherwise users will be able to browse your server (about comparatively their unix permissions).

Ok, I found that http://help.directadmin.com/item.php?id=183 was not really what I wanted to do as it meant using a whole php.ini file per user instead of just changes to the global php.ini. Here's what I have done to enable open_basedir per user which allows override of php.ini values:

Ok, I found that http://help.directadmin.com/item.php?id=183 was not really what I wanted to do as it meant using a whole php.ini file per user instead of just changes to the global php.ini. Here's what I have done to enable open_basedir per user which allows override of php.ini values:

Code:

|*if SUPHP="1"|
SetEnv PHP_INI_SCAN_DIR /home/|USER|/
|*endif|

I realize that I have done this on a per user basis rather than per domain, it should be straight forward to change if you do want it per domain.

Ok, fine. This right direction.
But I suggest you locate users php.ini in place unavailable for users. For example:

Code:

|
SetEnv PHP_INI_SCAN_DIR /usr/local/directadmin/data/users/|USER|/

otherwise users can be able modify php.ini setting such as open_basedir, disabled_functions, etc...

I've not tested this with suphp, but this schema works fine for me with mod_fastcgi, so it should work with suphp too.

PS. another way is setting chflags\chattr on your users php.ini files, but I think this way is more difficult for maintaince.

I was read about "suPHP doesn't allow the use of php_flag and php_value" and something like that above this link;

Correct, you can't use .htaccess files to specify PHP config options using suPHP. The howto explains how to create custom php.ini files for each user. If they want custom PHP config, you can specify it in their php.ini file (/home/user/php.ini)
The reason why you must not give the user's themselves access to change this file is because they can then change the open_basedir restriction.

Originally Posted by xmats

But why am I still seeing httpd processes owned by apache and not the local user?

Only PHP runs as the local user.. apache doesn't need to as it's not processing the code, it just creates a PHP process as the local user to execute it.
If you run top, you'll see a php-cgi processes running as the local user popping up when this happens.

I have done the above steps but now all my website are giving the following error: No input file specified does anyone have a solution for this problem ?

thanks.

I had the same problem. You have not entered correctly the open_basedir. You have to set for each user their correct open_basedir or do not set it at all. You'll find instructions above on how to set a php.ini file for each user with only the open_basedir statement in it