Looks like I will have a lot to say on this topic still. By now I’ve collected some cases when you can not use PHP in FastCGI mode and to keep the sites running you will need to abandon suEXEC nice and clean privilege separation mechanism in favor of mod_php/ASAPI.
Both discovered situations have their workarounds which mostly require redesign, but if you have commercial application or read-made web site that has to be deployed, you really don’t have any other choice then to switch back to mod_php
- Use of apache_note() function – this function is facilitating apache inter-module communication, so obviously PHP has to be apache module for that. In my opinion this seriously breaks PHP scripts portability prohibiting FastCGI API and limiting server to apache. In my case it was used to call Apache mod_geoip from PHP script, while PHP itself has perfectly functional geoip extension.
- Another situation is use of auto_prepend_file / auto_append_file on per-directory basis from .htaccess files – there is no configurable alternative with PHP in FastCGI mode, even though you have per-vhost php.ini. In this case to stay with FastCGI you will need to redesign your site to avoid using .htaccess for configuring PHP.
All in all, we will have to adjust our 00-fcgid.conf and Virtualmin vhost template so that we would be able to switch back to mod_php at any time (or even run both – I will add this directive to the template but I will test it later on and update this post).
All changes required are just properly put [cci lang=”apache”]
/etc/httpd/conf.d/00-fcgid.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
LoadModule fcgid_module modules/mod_fcgid.so <IfModule mod_fcgid.c> # this is unconfirmed - the idea is to turn off mod_php when mod_fcgid is loaded # experimental/dangerous - uncomment if you are sure of what you are doing # php_value engine off ProcessLifeTime 300 IPCCommTimeout 120 IPCConnectTimeout 120 MaxProcessCount 1500 DefaultMaxClassProcessCount 1500 DefaultMinClassProcessCount 0 # Sane place to put sockets and shared memory file SocketPath run/mod_fcgid SharememPath run/mod_fcgid/fcgid_shm #php suexec only PHP_Fix_Pathinfo_Enable 1 AddType application/x-httpd-php .php AddHandler php-fcgi .php Action php-fcgi /fcgi-bin/php-fcgi FCGIWrapper /var/www/cgi-bin/php-fcgi .php Alias /fcgi-bin/ /var/www/cgi-bin/ <Location /fcgi-bin/> SetHandler fcgid-script Options +ExecCGI </Location> DirectoryIndex index.php </IfModule> |
Now, for virtual host. We will want something, that looks like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<VirtualHost xx.xx.xx.xx:80> ServerName web1.com ServerAlias www.web1.com DocumentRoot /home/web1/public_html ErrorLog /home/web1/logs/error_log CustomLog /home/web1/logs/access_log combined ScriptAlias /cgi-bin/ /home/web1/cgi-bin/ DirectoryIndex index.html index.htm index.php index.php4 index.php5 <IfModule mod_fcgid.c> # if there is mod_php Alias /fcgi-bin/ /var/www/cgi-bin/ <Location /fcgi-bin/> SetHandler fcgid-script Options +ExecCGI </Location> SuexecUserGroup "#503" "#503" </IfModule> <Directory /home/web1/public_html> Options -Indexes IncludesNOEXEC FollowSymLinks +ExecCGI <IfModule mod_fcgid.c> AddHandler php-fcgi .php Action php-fcgi /fcgi-bin/web1/php-web1 FCGIWrapper /var/www/cgi-bin/web1/php-web1 .php </IfModule> Allow from all AllowOverride All </Directory> <Directory /home/web1/cgi-bin> Options ExecCGI Allow from all </Directory> </VirtualHost> |
This is what our virtualmin apache template to achieve such configuration from virtualmin should look like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
ServerName ${DOM} ServerAlias *.${DOM} DocumentRoot ${HOME}/public_html ErrorLog ${HOME}/logs/error_log CustomLog ${HOME}/logs/access_log combined ScriptAlias /cgi-bin/ ${HOME}/cgi-bin/ <IfModule mod_fcgid.c> Alias /fcgi-bin/ /var/www/cgi-bin/ <Location /fcgi-bin/> SetHandler fcgid-script Options +ExecCGI </Location> DirectoryIndex index.html index.htm index.php index.php4 index.php5 SuexecUserGroup "#${UID}" "#${GID}" </IfModule> <Directory ${HOME}/public_html> Options +ExecCGI -Indexes IncludesNOEXEC FollowSymLinks AllowOverride All <IfModule mod_fcgid.c> AddHandler php-fcgi .php Action php-fcgi /fcgi-bin/${USER}/php-${USER} </IfModule> Order allow,deny Allow from all </Directory> <Directory ${HOME}/cgi-bin> Options ExecCGI Allow from all </Directory> |
This will allow to switch from PHP/FastCGI to mod_php by toggling LoadModule on/off.
Note:
I got the problem:
[Fri Aug 19 23:40:00 2011] [error] [client 192.168.0.2] client denied by server configuration: /var/www/cgi-bin/dev/php-dev
[Fri Aug 19 23:40:00 2011] [error] [client 192.168.0.2] File does not exist: /home/dev/public_html/favicon.ico
I can not find where is the error. I followed every step to install apache and mod_fcgid. But the different is: mod_fcgid is built in apache, I don’t use it as module loaded in configuration.
I created all directories and set permission/owned as the same in article. Turn off SELinux…
I use Centos 5.5 on my localhost (virtualbox).
Please help me!
Did you check Apache suexec.log – it looks like something is not right with the permissions/ownership for /var/www/cgi-bin/dev/php-dev or the php script your are trying to execute.