如何设置Apache2与mod_fcgid和PHP5在OpenSUSE 12.3

本教程介绍如何在OpenSUSE 12.3上安装带有mod_fcgid和PHP5的Apache2。 mod_fcgid是旧的mod_fastcgi的兼容替代方案。 它允许您使用其所有者的权限执行PHP脚本,而不是Apache用户。

1初步说明

本教程中使用的是OpenSUSE 12.3服务器,主机名为server1.example.com ,IP地址为192.168.0.100

我将在本教程www.example1.comwww.example2.com中创建两个Apache vhost,以演示mod_fcgid的用法。

2安装Apache2 / mod_fcgi / PHP5

我们可以安装Apache2,mod_fcgid和PHP5,如下所示:

zypper install apache2 apache2-mod_fcgid php5-fastcgi

如果Apache2已经安装了PHP5作为Apache模块,请立即禁用PHP5模块:

a2dismod php5

下一步启用suexec和fcgid模块:

a2enmod suexec
a2enmod fcgid

然后我们创建Apache的系统启动链接并启动它:

systemctl enable apache2.service
systemctl start apache2.service

接下来我们打开/etc/php5/fastcgi/php.ini ...

vi /etc/php5/fastcgi/php.ini

...并取消注释行cgi.fix_pathinfo = 1

[...]
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
cgi.fix_pathinfo=1
[...]

打开/etc/apache2/conf.d/mod_fcgid.conf ...

vi /etc/apache2/conf.d/mod_fcgid.conf

...并添加行PHP_Fix_Pathinfo_Enable 1 (此行不能进入<VirtualHost>部分,因为那会得到此错误: PHP_Fix_Pathinfo_Enable不能在<VirtualHost>部分中发生 ):

[...]

PHP_Fix_Pathinfo_Enable 1
</IfModule>

然后重新启动Apache:

systemctl restart apache2.service

3为www.example1.com和www.example2.com创建Vhosts

我现在将创建两个vhosts: www.example1.com (使用文档root / srv / www / web1 / web )和www.example2.com (使用文档root / srv / www / web2 / web )。 www.example1.com将由用户和组web2由用户和组web1www.example2.com所有。

首先我们创建用户和组:

groupadd web1
groupadd web2
useradd -s /bin/false -d /srv/www/web1 -m -g web1 web1
useradd -s /bin/false -d /srv/www/web2 -m -g web2 web2
chmod 755 /srv/www/web1
chmod 755 /srv/www/web2

然后,我们创建文档根,并使其由用户/组web1或它们拥有。 web2

mkdir -p /srv/www/web1/web
chown web1:web1 /srv/www/web1/web
mkdir -p /srv/www/web2/web
chown web2:web2 /srv/www/web2/web

我们将使用suExec运行PHP; suExec的文档根目录是/ srv / www ,如下所示:

/usr/sbin/suexec2 -V
server1:~ # /usr/sbin/suexec2 -V
 -D AP_DOC_ROOT="/srv/www"
 -D AP_GID_MIN=96
 -D AP_HTTPD_USER="wwwrun"
 -D AP_LOG_EXEC="/var/log/apache2/suexec.log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=96
 -D AP_USERDIR_SUFFIX="public_html"
server1:~ #

因此,我们不能直接调用PHP二进制文件( / usr / bin / php-cgi ),因为它位于suExec的文档根目录之外。 由于suExec不允许符号链接,解决问题的唯一方法是为/ srv / www子目录中的每个网站创建一个包装器脚本; 然后,包装器脚本将调用PHP二进制文件/ usr / bin / php-cgi 。 包装器脚本必须由每个网站的用户和组拥有,因此我们需要每个网站的一个包装器脚本。 我将在/ srv / www / php-fcgi-scripts的子目录中创建包装器脚本,例如/ srv / www / php-fcgi-scripts / web1/ srv / www / php-fcgi-scripts / web2

mkdir -p /srv/www/php-fcgi-scripts/web1
mkdir -p /srv/www/php-fcgi-scripts/web2
vi /srv/www/php-fcgi-scripts/web1/php-fcgi-starter
#!/bin/sh
PHPRC=/etc/php5/fastcgi/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/bin/php-cgi
vi /srv/www/php-fcgi-scripts/web2/php-fcgi-starter
#!/bin/sh
PHPRC=/etc/php5/fastcgi/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/bin/php-cgi

PHPRC行包含php.ini文件所在的目录(即/ etc / php5 / fastcgi /转换为/etc/php5/fastcgi/php.ini )。 PHP_FCGI_MAX_REQUESTS是在fcgid进程停止并启动新请求之前的最大请求数。 PHP_FCGI_CHILDREN定义将启动的PHP子代数

php-fcgi-starter脚本必须是可执行的,它们(以及它们所在的目录)必须由网站的用户和组拥有:

chmod 755 /srv/www/php-fcgi-scripts/web1/php-fcgi-starter
chmod 755 /srv/www/php-fcgi-scripts/web2/php-fcgi-starter
chown -R web1:web1 /srv/www/php-fcgi-scripts/web1
chown -R web2:web2 /srv/www/php-fcgi-scripts/web2

现在我们为www.example1.comwww.example2.com创建Apache vhosts:

vi /etc/apache2/vhosts.d/www.example1.com.conf
<VirtualHost *:80>
  ServerName www.example1.com
  ServerAlias example1.com
  ServerAdmin webmaster@example1.com
  DocumentRoot /srv/www/web1/web/

  <IfModule mod_fcgid.c>
    SuexecUserGroup web1 web1
    <Directory /srv/www/web1/web/>
      Options +ExecCGI
      AllowOverride All
      AddHandler fcgid-script .php
      FCGIWrapper /srv/www/php-fcgi-scripts/web1/php-fcgi-starter .php
      Order allow,deny
      Allow from all
    </Directory>
  </IfModule>

  # ErrorLog /var/log/apache2/error.log
  # CustomLog /var/log/apache2/access.log combined
  ServerSignature Off

</VirtualHost>
vi /etc/apache2/vhosts.d/www.example2.com.conf
<VirtualHost *:80>
  ServerName www.example2.com
  ServerAlias example2.com
  ServerAdmin webmaster@example2.com
  DocumentRoot /srv/www/web2/web/

  <IfModule mod_fcgid.c>
    SuexecUserGroup web2 web2
    <Directory /srv/www/web2/web/>
      Options +ExecCGI
      AllowOverride All
      AddHandler fcgid-script .php
      FCGIWrapper /srv/www/php-fcgi-scripts/web2/php-fcgi-starter .php
      Order allow,deny
      Allow from all
    </Directory>
  </IfModule>

  # ErrorLog /var/log/apache2/error.log
  # CustomLog /var/log/apache2/access.log combined
  ServerSignature Off

</VirtualHost>

确保您填写正确的路径(以及SuexecUserGroup行中的正确用户和组)。

打开/etc/apache2/httpd.conf ,并在Include /etc/apache2/vhosts.d/*.conf行之前添加NameVirtualHost行(否则只有第一个vhost将工作):

vi /etc/apache2/httpd.conf
[...]
### Virtual server configuration ############################################
#
# VirtualHost: If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at
# <URL:http://httpd.apache.org/docs-2.2/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.
#
NameVirtualHost *:80

Include /etc/apache2/vhosts.d/*.conf
[...]

在重新启动Apache之前,我们更改了suExec可执行文件的权限(否则,当您重新启动Apache时,您将看到以下警告: 警告:SuexecUserGroup伪指令需要SUEXEC包装器。 ):

chmod 4755 /usr/sbin/suexec2

之后重新启动Apache:

systemctl restart apache2.service

4测试

现在我们创建一个小的PHP测试文件,例如在www.example1.com网站上...

vi /srv/www/web1/web/info.php
<?php
phpinfo();
?>

...并在浏览器中调用该文件( http://www.example1.com/info.php )。 如果一切顺利,输出应该与此类似,您应该在Server API行中看到CGI / FastCGI

每个网站的自定义php.ini

因为每个网站都有自己的php-fcgi-starter包装器脚本,所以可以为不同的网站定义不同的php.ini文件。 为了演示这一点,我将把默认的php.ini/etc/php5/fastcgi/php.ini )复制到/ srv / www / web2 /目录,并使www.example2.com/ srv中使用php.ini / www / web2 /目录:

cp /etc/php5/fastcgi/php.ini /srv/www/web2/
chown web2:web2 /srv/www/web2/php.ini

(您现在可以将/srv/www/web2/php.ini修改为您的喜好)

然后我们打开/ srv / www / php-fcgi-scripts / web2 / php-fcgi-starter ...

vi /srv/www/php-fcgi-scripts/web2/php-fcgi-starter

...和put / srv / www / web2 /PHPRC行中:

#!/bin/sh
PHPRC=/srv/www/web2/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/bin/php-cgi

之后重新启动Apache:

systemctl restart apache2.service

创建一个新的phpinfo(); 文件www.example2.com ...

vi /srv/www/web2/web/info.php
<?php
phpinfo();
?>

...并在浏览器中调用( http://www.example2.com/info.php )。 加载配置文件行现在应显示/srv/www/web2/php.ini

6更改单个PHP配置设置

而不是将全新的php.ini文件传递到您的网站,您还可以通过将-d开关添加到PHP来更改php-fcgi-starter包装器脚本中的单个PHP配置设置(或使用两者的组合)可执行。 例如,如果我想禁用web_example2.commagic_quotes_gpc ,我可以这样做:

vi /srv/www/php-fcgi-scripts/web2/php-fcgi-starter
#!/bin/sh
PHPRC=/etc/php5/fastcgi/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/bin/php-cgi -d magic_quotes_gpc=off

之后重新启动Apache:

systemctl restart apache2.service

然后在浏览器( http://www.example2.com/info.php )中再次调用info.php脚本,并搜索magic_quotes_gpc行 - 现在应该显示:

7链接

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏