[BlueOnyx:20168] Re: Secure PHP options

Michael Stauber mstauber at blueonyx.it
Tue Oct 18 22:33:20 -05 2016


Hi Ernie,

> Nowadays there are 3 different methods of secure PHP for a vsite that I can
> see.
> 
> PHP (DSO) + mod_ruid2
> suPHP
> FPM/FastCGI
> 
> suPHP is the only one I have used in the past.
> 
> Which one is the most efficient nowadays but still supports individual vsite
> php.ini files?
> 
> I ask because suPHP grinds to a halt when web crawlers try to index things
> like Wordpress and Joomla sites, by spawing off a zillion php-cgi processes,
> so I am looking at trying one of the other methods of secure PHP.

Yeah, there is probably no perfect one-size-fits-all solution here.
Speed wise and performance wise the best to worst seems to be this:

- PHP (DSO) + mod_ruid2
- PHP-FPM
- suPHP

Only during usage of suPHP a separate php.ini will be used. So let us
look at the other two options:

PHP (DSO) + mod_ruid2:
=======================

This works similar to the regular DSO method of PHP. But an extra module
(mod_ruid2) is used, which will make sure that all PHP scripts are
executed under the UID/GID that's specified in the Apache config of this
Vsite.

The benefit of this is: We get the speed of the regular DSO execution of
PHP scripts, but avoid all the ownership issues that regular DSO usage
has. Because that would execute everything as user "apache".

All the PHP related variables and tweaks applicable for the Vsite will
still be applied. But not through a php.ini modification, but through
"php_admin_flag" and "php_flag" settings in the Apache <VirtualHost>
container of that Vsite.

This will override the settings in the main server wide php.ini, which
will still be used.

In my opinion this is as good as it gets. It locks down PHP, runs
scripts with the UID/GID of the web-owner and Vsite and the site
specific PHP settings still apply. It also has zero ill side effects
such as .htacces problems or others.

DSO + mod_ruid2 allows you to only run all Vsites that use it on the
same PHP version. This can either be 5.4.16 (the OS supplied version) or
one of the PHP versions from the shop. But all Vsites that use DSO +
mod_ruid2 *must* use the same version of PHP.

That's the only real limitation.


PHP-FPM/FCGI:
==============

We had our fair share of problems with the implementation of this, but
recent input from Darren Wolfe helped us to fix them all. So there are
no longer issues with .htaccess files if you use this method.

Each Vsite that uses PHP-FPM gets its own PHP-FPM config file and
PHP-FPM will listen on a specific localhost port for events pertaining
to that Vsite only. If Apache encounters a request for PHP page of that
Vsite, it contacts the PHP-FPM daemon on the localhost reserved for that
Vsite. The PHP-FPM daemon then processes the PHP page with the PHP
configuration specified for that Vsite.

Example: /etc/php-fpm-5.6.d/site2.conf on my test box

[...]
; UID/GID:
user = site2_admin
group = site2

; Set to 'ondemand' and set limits:
pm = ondemand
pm.max_children = 15
pm.process_idle_timeout = 10s
pm.max_requests = 500

; Set session path to a directory owned by process user
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session

; PHP Vsite settings
php_admin_flag[register_globals] = Off
php_admin_flag[allow_url_fopen] = Off
php_admin_flag[allow_url_include] = Off
php_admin_value[open_basedir] =
/var/lib/php/session/:/usr/sausalito/configs/php/:/tmp/:/home/solarspeed/php-5.6/share/pear:/home/.sites/143/site2/
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 5M
php_admin_value[max_execution_time] = 30
php_admin_value[max_input_time] = 60
php_admin_value[max_input_vars] = 1000
php_admin_value[memory_limit] = 128M
php_admin_flag[mail.add_x_header] = On
php_admin_value[sendmail_path] = /usr/sausalito/sbin/phpsendmail
php_admin_value[auto_prepend_file] =
/usr/sausalito/configs/php/set_php_headers.php
; From /home/.sites/143/site2/php.d/:
php_flag[display_errors] = Off
php_flag[log_errors] = On
php_flag[zlib.output_compression] = Off
php_flag[magic_quotes_gpc] = Off
php_flag[magic_quotes_runtime] = Off
php_flag[zend.ze1_compatibility_mode] = Off
php_flag[suhosin.session.encrypt] = Off
php_flag[session.auto_start] = Off
php_value[session.gc_maxlifetime] = 21600
php_value[session.gc_divisor] = 500
php_value[session.gc_probability] = 1
php_value[mbstring.func_overload] = 0

This uses the server wide php.ini for FPM, too. But the PHP-FPM config
for this Vsite has also the overrides for the PHP settings that we
configured for this Vsite through the GUI.

So PHP-FPM spawns a process, renders the page with the given settings
and returns them to Apache, which serves the results to the visitor.

While this is by leaps and bounds faster than suPHP, it is also not
without drawbacks: It spawns a process for every page that needs to be
processed. We can limit how many processes may be spawned and we can
configure time outs. But this might not be the most ideal way of doing
things in a high load / high traffic environment.

However: It is a very convenient way of making different versions of PHP
available at the same time to different Vsites, as we can easily do this
with PHP-FPM (and suPHP).


My bottom-line:
================

If speed or load is an issue: Use DSO + mod_ruid2, but keep in mind that
you have to pick a certain PHP version for this that's then used server
wide for both regular DSO usage *and* DSO + mod_ruid2.

For anything that requires a specific PHP version *other* than the one
that you use DSO/DSO+mod_ruid2 for use PHP-FPM instead.

If slow speed is not an issue, use suPHP instead.

If the separate php.ini is a must in your eyes? You can set most PHP
settings via "php_admin_flag" and "php_flag" in the VirtualHost
container. If need be (and to prevent the GUI from overriding them) you
can also put them into the PHP-FPM config or can put them (for the DSO
versions) into the siteX.include files under /etc/httpd/conf.d/vhosts/

-- 
With best regards

Michael Stauber



More information about the Blueonyx mailing list