Раздел: Админство

Настройка собственной сборки PHP в Apache через FastCGI на CentOS 7

Обычно, я не качаю PHP из репозиториев, а собираю сам. Это обусловлено тем, что для работы требуются разные сборки разным сайтам и конфигурируя PHP самостоятельно всегда знаешь, что и как настроено. В интернете полно инструкций о том, как настроить Apache с php и fcgi с PHP из репозиториев, но, натолкнувшись на определённые трудности, я решил сделать об этом отдельный пост.

1. Директории.
Предлагаю следующую структуру:
/www/ — корневая директория с сайтами.
/www/cgi-bin/ — папка для обёрток fcgi. В ней будут отдельные папки для обёрток для каждого сайта.
/www/cgi-bin/mysite.ru/ — папка с обёрткой для нашего тестового сайта mysite.ru
/www/http/ — папка с сайтами
/www/http/mysite.ru/ — наш тестовый сайт
/www/http/mysite.ru/html/ — файлы сайта
/www/http/mysite.ru/logs/ — логи сайта
/opt/php/ — папка с PHP для разных проектов
/opt/php/mysite.ru — папка с PHP для нашего тестового проекта

mkdir /www /www/cgi-bin /www/cgi-bin/mysite.ru /www/http /www/http/mysite.ru /www/http/mysite.ru/html /www/http/mysite.ru/logs /opt/php /opt/php/mysite.ru

2. Права доступа
Для контроля доступа к папкам создадим отдельную группу mysite.ru и пользователя mysite.ru:

groupadd mysite.ru
useradd -s /bin/false -d /www/http/mysite.ru -m -g mysite.ru mysite.ru

Этот шаг нельзя пропускать, т.к. fastcgi должен работать через обычный, не системынй аккаунт.

Назначаем права на папку с сайтом:

chown mysite.ru:mysite.ru /www/http/mysite.ru/html/

3. Собираем PHP
Как собрать php именно вам — решайте сами. В данном примере — сборка, предназначенная для CMS 1С-Битрикс. Главное, что в ней присутствует параметр «—enable-cgi» — то, что нам необходимо для нашей задачи.

Чтобы избежать проблем с нехватающими библиотеками при сборке, рекомендую сразу поставить:

yum install libxml2-devel openssl-devel libjpeg-turbo-devel libpng-devel freetype-devel libmcrypt-devel libapreq2-devel

Скачиваем исходники PHP с сайта php museum. Мне, например, нужна посредняя сборка 5й версии — 5.6.24:

wget http://museum.php.net/php5/php-5.6.24.tar.gz

Распаковываем:

tar -zxvf php-5.6.24.tar.gz

Заходим в папку и конфигурируем php:

cd php-5.6.24
./configure --prefix=/opt/php/mysite.ru --with-config-file-path=/www/http/mysite.ru --with-mysqli --with-mysql --with-gd --with-jpeg-dir --enable-mbstring --with-mcrypt --enable-zip --with-zlib --enable-cli --enable-cgi --with-freetype-dir=/usr/include/freetype2/ --with-openssl --with-pear

Обратите внимание — параметр —with-config-file-path=/www/http/mysite.ru указывает на то, что файл php.ini должен будет располагаться в папке сайта /www/http/mysite.ru
Для меня это удобно, т.к. обычно именно к этой папке присоединяется программист по FTP для работы с сайтом, и он должен иметь возможность изменять php.ini (не в продакшене, конечно).

Далее — компиляция(будет долго) и установка:

make
make install

После установки выставляем права:

chmod ugo+rX -R /opt/php/mysite.ru/

Положим php.ini в соответствующую директорию:
/www/http/mysite.ru/php.ini
В него необходимо установить следующий параметр для корректной работы fcgi:

cgi.fix_pathinfo = 1

Какой php.ini необходим для Битрикса — смотрите в специальной статье, посвящённой этому вопросу.

4. Apache
Установка:

yum install httpd

Ставим модуль fcgid для Апача:

yum install mod_fcgid

Добавим файл конфига нашего сайта:
/etc/httpd/conf.d/mysite.ru.conf

<VirtualHost mysite.ru:80>
	ServerName mysite.ru
	ServerAlias www.mysite.ru
	DocumentRoot /www/http/mysite.ru/html
	<IfModule mod_fcgid.c>
		SuexecUserGroup mysite.ru mysite.ru
		FcgidBusyTimeout 3600
		FcgidIOTimeout 600
		FcgidConnectTimeout 600
		<Directory /www/http/mysite.ru/html>
			DirectoryIndex index.php index.html
			Options FollowSymLinks
			AddHandler fcgid-script .php
			Options +ExecCGI
			FcgiWrapper /www/cgi-bin/mysite.ru/mysite.ru.fcgi .php
 			AllowOverride All
 			Require all granted
		</Directory>
	</IfModule>
	ErrorLog /www/http/mysite.ru/logs/error.log
	CustomLog /www/http/mysite.ru/logs/access.log common
</VirtualHost>

Добавляем обёртку fastcgi для нашего сайта
/www/cgi-bin/mysite.ru/mysite.ru.fcgi

#!/bin/sh
exec /opt/php/mysite.ru/bin/php-cgi

И даём на неё права:

chown -R mysite.ru:mysite.ru /www/cgi-bin/mysite.ru/
chmod 755 /www/cgi-bin/mysite.ru/mysite.ru.fcgi

Добавим в файл с настройками модуля fcgid параметр PHP_Fix_Pathinfo_Enable 1:

echo "PHP_Fix_Pathinfo_Enable 1" >> /etc/httpd/conf.d/fcgid.conf

Добавляем в статичный кеш DNS для нашего тестового сайта:

echo "127.0.0.1    mysite.ru" >> /etc/hosts

5. Настройка suexec

Посмотрим текущие настройки suexec:

/usr/sbin/suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_SYSLOG
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=500
 -D AP_USERDIR_SUFFIX="public_html"

Т.к. у нас корневая папка всех сайтов — /www, нам необходимо поменять параметр AP_DOC_ROOT с «/var/www» на «/www».

Для этого нам нужно будет скачать исходники apache (той же версии, что установлена на сервере).
Проверка текущей версии:

httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Apr 12 2017 21:03:28

Заходим сюда и ищем нужную версию. Качаем:

cd .. #выходим из папки с php
wget http://archive.apache.org/dist/httpd/httpd-2.4.6.tar.gz

Распаковываем и заходим в папку:

tar -zxvf httpd-2.4.6.tar.gz
cd httpd-2.4.6/

Конфигурируем и компилируем, но не инсталлируем(!).
Обратите внимание: —with-suexec-docroot=/www это наша корневая папка со всеми сайтами,
—with-suexec-logfile=»/www/suexec.log» это место для логов suexec. Эти параметры указать обязательно.

./configure --enable-suexec --with-suexec-caller=apache --with-suexec-userdir=public_html --with-suexec-docroot=/www --with-suexec-uidmin=500 --with-suexec-gidmin=100 --with-suexec-logfile="/www/suexec.log"
make

Смотрим, какие текущие права у suexec:

ls -lat /usr/sbin/suexec
-r-x--x---. 1 root apache 15360 Apr 12 23:04 /usr/sbin/suexec

Копируем с заменой скомпилированный нами файл и назначаем ему соответствующие права:

cp support/suexec /usr/sbin/suexec
chown root:apache /usr/sbin/suexec
chmod 4510 /usr/sbin/suexec

Проверяем:

/usr/sbin/suexec -V
 -D AP_DOC_ROOT="/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_EXEC="/www/suexec.log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=500
 -D AP_USERDIR_SUFFIX="public_html"

6. Проверка
Для проверки сайта выведем phpinfo:

echo "<?php phpinfo(); ?>" > /www/http/mysite.ru/html/index.php

Перезапустим апач:

service httpd restart

Всё, сайт должен быть доступен с хоста по http://mysite.ru/

Как видим, php работает через fcgi:

VirtualBox_2017-07-15_11-15-51

cgi-fcgi


Траблшутинг.

Если на этапе конфигурации suexec выпадает ошибка:

configure: Configuring Apache Portable Runtime library...
configure:
checking for APR... no
configure: error: APR not found.  Please read the documentation.

Скорее всего, не установлен пакет libapreq2-devel.
Решение:

yum install libapreq2-devel

Если при старте апача возникает ошибка типа такой:

Jul 14 23:11:41 localhost.localdomain setroubleshoot[29112]: failed to retrieve rpm info for /www/cgi-bin/mysite.ru/mysite.ru.fcgi
Jul 14 23:11:41 localhost.localdomain setroubleshoot[29112]: SELinux is preventing /usr/sbin/httpd from getattr access on the file /www/cgi-bin/mysite.ru/mysite.ru.fcgi. For complete SELinux messages. run sealert -l a93db787-0e3b-48bb-95f6-0185b8f9565f
Jul 14 23:11:41 localhost.localdomain python[29112]: SELinux is preventing /usr/sbin/httpd from getattr access on the file /www/cgi-bin/mysite.ru/mysite.ru.fcgi.

*****  Plugin catchall_labels (83.8 confidence) suggests   *******************

If you want to allow httpd to have getattr access on the mysite.ru.fcgi file
Then you need to change the label on /www/cgi-bin/mysite.ru/mysite.ru.fcgi
Do
# semanage fcontext -a -t FILE_TYPE '/www/cgi-bin/mysite.ru/mysite.ru.fcgi'
where FILE_TYPE is one of the following: NetworkManager_exec_t, NetworkManager_log_t, NetworkManager_tmp_t, abrt_dump_oops_exec_t, abrt_etc_t, abrt_exec_t, abrt_handle_event_exec_t, abrt_helper_exec_t, abrt_retrace_coredump_exec_t, abrt_retrace_spool_t, abrt_retrace_worker_
Then execute:
restorecon -v '/www/cgi-bin/mysite.ru/mysite.ru.fcgi'


*****  Plugin catchall (17.1 confidence) suggests   **************************

If you believe that httpd should be allowed getattr access on the mysite.ru.fcgi file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -i my-httpd.pp

Попробуйте отключить Selinux:

setenforce 0

Если браузер выдаёт ошибку 500, а в логах сайта /www/http:/mysite.ru/logs/error.php видим следующее:

[Fri Jul 14 23:49:16.566589 2017] [fcgid:warn] [pid 10475] (104)Connection reset by peer: [client 127.0.0.1:43146] mod_fcgid: error reading data from FastCGI server
[Fri Jul 14 23:49:16.566611 2017] [core:error] [pid 10475] [client 127.0.0.1:43146] End of script output before headers: index.php

Это значит, что некорректно настроен suexec.
Обратитесь к пункту 5 данной инструкции.


Если в логах апача /etc/httpd/log/error.log мы видим такую ошибку

suexec failure: could not open log file
fopen: Permission denied

скорее всего, некорректно настроен suexec — не существует путь для лог-файла.
Обратитесь к пункту 5 данной инструкции.


Если в логах suexec /www/suexec.log мы видим:

suexec policy violation: see suexec log for more details

Значит, некорректно созданы юзеры — UID учётной записи меньше 500, используется системная учётка вместо пользовательской или пользователю даны некорректные права.
Обратитесь к пункту 2 данной инструкции.

Комментировать

Комментарии

девятнадцать + один =