-
-
Notifications
You must be signed in to change notification settings - Fork 461
apache2 with fcgid
Because you can run PHP with different users according to the vHost, which means its easier to protect each vHost from attacks by another vHost. On the other site there are no more problems between permissions of the FTP- and the Webserver-user or compromised hosts.
Running PHP as a CGI would require reloading the PHP binary for every request which would lead to a massive overhead. This is why there is FastCGI, it loads the binary only once and hands requests to PHP by redirecting stdin and stdout by pipes/sockets.
The old mod_fastcgi doesn't seem to be in development anymore and wasn't released under the GPL. mod_fcgid http://fastcgi.coremail.cn/ is the implementation of the FastCGI protocol under the GPL, its actively developed and has a better process management (Supports MPM and Thread Management).
Pro:
- Fast + Secure. PHP is thread safe that way so you can use Apache mpm-worker for better performance.
- Individual php.ini per customer
- No permission problems between the FTP- and Webserver-users
Cons:
- Complex to set up
- Wrong installations can cause more security holes than using the original mod_php5 module
- A lot of RAM is used when there are a lot of vHosts (can be limited slightly)
I assume that you have Froxlor already running and the database set up.
First you should ensure that the Froxlor cronjob isn't executed while you set up mod_fcgid. This could produce unwanted results!
/etc/init.d/cron stop
In order to have suexec work, you need real usernames as suexec cannot work with virtual user IDs Froxlor uses. We must get libnss-mysql to read users from MySQL. The FTP table in the Froxlor database provides us with every information we need. To avoid any bottlenecks that might happen with big directories we install the name service caching daemon 'nscd'.
apt-get install libnss-mysql nscd
Now copy and paste the actual configuration files from the Froxlor panel and apply them to your file system. You'll need the to create or update the following files (templates in your Froxlor panel in menu: "Configuration"):
- /etc/nss-mysql-root.conf
- /etc/nss-mysql.conf
- /etc/nsswitch.conf
Make sure that only root can read those configs since they include your Froxlor database password!
chmod 600 /etc/nss-mysql.conf /etc/nss-mysql-root.conf
Restard nscd now
/etc/init.d/nscd restart
Now it should already work. To find out if it really works just go to a directory that was created by Froxlor and check if the user ID got replaced by the username.
ls -al /var/customers/webs/
This should produce a result like:
drwxr-xr-x 3 web1 web1 4096 2008-06-13 17:18 web1
drwxr-xr-x 8 web2 web2 4096 2009-01-02 17:40 web2
drwxr-xr-x 10 web3 web3 4096 2009-01-25 13:33 web3
If you don't see a result like this or just the virtual user IDs, check your configs and if the users really exist. If nscd isn't working properly you cannot continue with the next steps.
On the very first beginning I want to explain some general things about suexec since this produces the most confusion. If you specify the SuexecUserGroup directive in a vHost in combination with a directory which has the ExecCGI option enabled, the suexec module will first switch its user ID in a new thread if a new client has connected. After that the starter script will be executed to set up some environment options for the CGI binary, which is PHP in our case. This starter script will then run the PHP CGI binary. In order that this works it must be possible for the PHP process to communicate with Apache to redirect its in and output (stdin/stdout). This is the normal behavior for all CGI applications. In our case this redirection is managed by FastCGI/mod_fcgid.
Independent of the options with which suexec has been compiled you can store the files of the customers wherever you want. I recommend to store all of them under the default path (/var/customers/webs/). And also Froxlor should be within this directory, so its easier for you to manage all in all.
Never store the customer files beside the php.ini and starter directory, this is a security problem! The customer could be able to modify security relevant settings. On the other site Froxlor will override this settings anyway if something has changed.
Please don't forget that the starter scripts must be always stored under the path with which suexec has been compiled. This is a security feature of suexec, so don't try to hack it. If you need to modify the original path, recompile suexec on your own.
This howto was created for the default options from Debian, Ubuntu and SuSE so you don't need to compile anything new. To find out which is the default path for your suexec binary, run
apt-get install apache2-suexec
/usr/lib/apache2/suexec -V
For Debian this could produce a result like this. Important is the path specified in AP_DOC_ROOT.
-D AP_DOC_ROOT="/var/www"
-D AP_GID_MIN=100
-D AP_HTTPD_USER="www-data"
-D AP_LOG_EXEC="/var/log/apache2/suexec.log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=100
-D AP_USERDIR_SUFFIX="public_html"</pre>
You can continue with this section if you use a distribution like Debian, Ubuntu or SuSE. If you use /var/www/ as the place to store your starter scripts you can use the standard suexec binary that comes with your distribution. (If you don't use /var/www/ as the place to store your starter scripts, you can see section Using-suexec-custom) I recommend that by the way! If you wonder why suexec isn't called suexec2 on Debian, don't worry - the versions are correct, just the binaries got renamed.
Enable suexec (otherwise apache won't know the directive SuexecUserGroup) by typing this in a root shell:
a2enmod suexec
Now restart Apache with
/etc/init.d/apache2 restart
If you don't see any new errors or warnings than without suexec you can continue with the next section. Otherwise check the logs, they will help you.
(debain wheezy/jessie based instructions) Install the suexec-custom package
apt-get install apache2-suexec-custom
If you use the normal suexec binary, apt-get shall remove suexec first and than install suexec-custom. After the Installation you can (normaly) edit this file "@/etc/apache2/suexec/www-data@"
The file contains 2 important lines: /var/www/ public_html/cgi-bin
# /Path/to/store/your/fcgi-scripts/
# (please expand) I don't know, but comment it out like this ''#public_html/cgi-bin''
Enable suexec (otherwise apache won't know the directive SuexecUserGroup) by typing this in a root shell:
a2enmod suexec
Now restart Apache with
/etc/init.d/apache2 restart
Now follow the next steps and customize the fcgi path in Froxlor
You'll now have to tell Froxlor to create the starter scripts and the correct directives in the vHosts. Do this by activating the option Include PHP via mod_fcgid/suexec in the control panel options (just enable FCGID in the settings page). All other options for this module should be all ok by the default values. Just check if FCGIWrapper is enabled for the inclusion of the starter scripts in the vHosts - this is the easiest solution to get it running.
Now we need to install and enable mod_fcgid
apt-get install libapache2-mod-fcgid
a2enmod fcgid
Restart apache to enable the prvious installed modules
/etc/init.d/apache2 restart
First we need the PHP CGI binary. Install it via
apt-get install php5-cgi
Make sure that everything is ok by running
php-cgi -v
The output should be similar to this:
PHP 5.6.30-0+deb8u1 (cgi-fcgi) (built: Feb 8 2017 08:50:21)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2006 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
It's important that you can find cgi and fcgi or fcgid in the output, otherwise something went wrong. If you don't see the output of Suhosin its ok - that is just a security patch for PHP. (My recommendation is to use this patch!)
Now that we have all set up, we will enable suexec for Froxlor.
Froxlor user creation
I think having an own user for Froxlor is a nice solution as we don't want FTP access for it anyway.
useradd -s /bin/false -U froxlorlocal
The Start-script and php.ini for Froxlor will automatically be generated by Froxlor itself.
To enable this setting, login as Admin, visit the Settings-Menu (Submenu FCGID) and check the "Enable FCGID for the Froxlor vhost" box.
You need to make the Froxlor-Directory readable for the fcgid-enviorment.
chown -R froxlorlocal:froxlorlocal /var/www/froxlor
Now reload the Apache configuration and open Froxlor in your browser.
/etc/init.d/apache2 restart
Log into Froxlor and check the Webserver-Interface for CGI-FCGI. Froxlor now runs under the froxlorlocal user!
After all is working make sure to disable the default mod_php5 modules in Apache. Otherwise this would be a security hole in your new setup!
a2dismod php5
Get into Froxlor and klick Rebuild Configuration Files.
Force the cronjob once to run to create the fcgi settings for all domains
/usr/bin/php5 /var/www/froxlor/scripts/froxlor_master_cronjob.php --force --debug
Don't forget to start Cron again.
/etc/init.d/cron start
If you have set up all correctly it should be now possible to open the customer domains in your browser. If there are PHP child processes under the Apache process all is working fine. You can also check that by running phpinfo(); from a file within a customer domain.
To check if there are child processes, run
ps faux
This should produce a result like this:
root 18486 0.0 0.5 21896 10772 ? Ss Jan25 0:00 /usr/sbin/apache2 -k start
www-data 18681 0.0 0.3 20824 7692 ? S Jan25 0:00 \_ /usr/sbin/apache2 -k start
www-data 18682 0.0 0.3 21156 7740 ? S Jan25 0:00 \_ /usr/sbin/apache2 -k start
web1 18969 0.0 0.4 19952 8216 ? S Jan25 0:21 | \_ /usr/bin/php5-cgi -c /var/www/php-fcgi-scripts/web1/example.com/
web2 18972 0.0 0.3 19464 6376 ? S Jan25 0:03 | \_ /usr/bin/php5-cgi -c /var/www/php-fcgi-scripts/web2/example.org/
web3 19002 0.0 0.3 19660 7452 ? S Jan25 0:01 | \_ /usr/bin/php5-cgi -c /var/www/php-fcgi-scripts/web3/example.net/
There are like 1 billion problems you might have to face ;)
- First get nss-mysql and nscd running
- Dont forget to restart nss-mysql and nscd
- suexec is often a problem. Make sure you configure it right at compile time. For the default distribution packages check /var/log/apache2/suexec.log for errors.
- 500 Internal Server Error - Check the logs! Often you can find the solution by the given errors. This may help you further http://htmlfixit.com/cgi-tutes/tutorial_Common_Web_dev_error_messages_and_what_they_mean.php
- Enabled debug logging for apache and restart it. (LogLevel debug in /etc/apache2/apache2.conf) Be sure to uncomment this line and do a restart of apache after debugging!
- Be sure that /etc/apache2/logs/fcgidsock is owned by www-data. Otherwise you will get the typical error Premature end of script headers, which says that PHP isn't able to communicate with the apache process.
- Look at the logs!!!
- ps faux and look if there is a PHP process running under the apache process.
- strace -s 2000 -ff -o /tmp/fastcgi -p Very useful if you know how to debug!
- If you edit config files, please dont use WinSCP. This adds Windows format and Linux can't work with this.
Got problems?
If you got problems with this howto please let us/me know. But please prefer to use the Forum instead of the Bugtracker or IRC. Thanks!
- http://fastcgi.coremail.cn/
- http://httpd.apache.org/docs/2.0/suexec.html
- http://www.seaoffire.net/fcgi-faq.html
- http://wiki.osuosl.org/display/howto/apache2+suexec+fastcgi+php
- http://alain.knaff.lu/howto/PhpSuexec/
- http://www.debianhowto.de/doku.php/de:howtos:sarge:apache2_php-fcgi
- http://www.trilithium.com/johan/2005/04/apache2-fastcgi/