
При переносе панели управления BrainyCP с прямого доступа по IP-адресу на отдельный поддомен может возникнуть неожиданная проблема: панель открывается, логин и пароль правильные, но после нажатия кнопки входа пользователь снова оказывается на странице авторизации.
Особенно часто подобная ситуация возникает на серверах, где одновременно размещено несколько сайтов, использующих PHP-сессии с cookie PHPSESSID .
В этой статье рассмотрим практическую настройку BrainyCP на поддомене с HTTPS, подключение через Apache reverse proxy и устранение конфликта PHP-сессий с помощью отдельного имени cookie BRAINYSESSID .
Предположим, что BrainyCP доступен непосредственно по адресу:
https://82.39.214.228:8000
При этом необходимо сделать нормальный адрес панели:
https://panel.example.com
После настройки HTTPS и reverse proxy сама панель может открываться нормально, однако авторизация не работает: после ввода правильных данных снова появляется форма входа.
Одна из возможных причин — конфликт cookies PHP-сессий.
Например, браузер может одновременно хранить:
PHPSESSID=...
Domain: .example.com
Path: /
и:
PHPSESSID=...
Domain: panel.example.com
Path: /
Для разных сайтов это может привести к тому, что приложение получает не ту сессию, которую ожидает.
В случае со старой версией BrainyCP проблема особенно заметна, поскольку панель использует PHP-сессию непосредственно при проверке авторизации.
После настройки запрос к панели проходит следующую цепочку:
Браузер
|
v
panel.example.com:443
|
v
Apache
|
v
127.0.0.1:8002
|
v
nginx BrainyCP
|
v
PHP-FPM BrainyCP
|
v
BRAINYSESSID
При этом обычные сайты сервера продолжают использовать стандартный:
PHPSESSID
А сама панель BrainyCP получает отдельную cookie:
BRAINYSESSID
Сначала необходимо убедиться, что поддомен панели указывает на сервер.
Например:
panel.example.com
Проверяем DNS:
dig +short panel.example.com
В результате должен отображаться IP-адрес сервера.
BrainyCP в рассматриваемой конфигурации использует nginx на портах 8000 и 8002 .
Проверяем HTTPS:
curl -k -I https://127.0.0.1:8000
И HTTP:
curl -I http://127.0.0.1:8002
Если сервер отвечает кодом 200 , значит сама панель работает, и проблему нужно искать в способе доступа к ней.
Для доступа к панели по HTTPS удобно использовать сертификат Let's Encrypt.
Проверяем наличие сертификата:
ls -la /etc/letsencrypt/live/panel.example.com/
Обычно здесь находятся следующие файлы:
cert.pem
chain.pem
fullchain.pem
privkey.pem
Если Apache уже принимает входящие HTTPS-запросы на 443 порту, можно передать запросы панели на локальный nginx BrainyCP.
Создаём конфигурацию:
nano /etc/httpd/conf.d/panel.example.com.conf
Добавляем:
<VirtualHost IP-АДРЕС-СЕРВЕРА:443>
ServerName panel.example.com
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/panel.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/panel.example.com/privkey.pem
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8002/
ProxyPassReverse / http://127.0.0.1:8002/
ErrorLog /var/log/httpd/panel.example.com-error.log
CustomLog /var/log/httpd/panel.example.com-access.log combined
</VirtualHost>
Проверяем конфигурацию Apache:
httpd -t
Если получаем:
Syntax OK
перезагружаем конфигурацию Apache:
systemctl reload httpd
После этого проверяем доступность панели:
curl -k -I https://panel.example.com
Если получаем ответ 200 , reverse proxy работает.
При использовании reverse proxy появляется дополнительный уровень между браузером и PHP-FPM:
Браузер → Apache → nginx → PHP-FPM
Поэтому необходимо корректно передавать реальный IP посетителя.
Создаём или проверяем файл:
nano /etc/httpd/conf.d/remoteip.conf
Содержимое:
<IfModule remoteip_module>
RemoteIPHeader X-Forwarded-For
</IfModule>
Проверяем конфигурацию:
httpd -t
И перезагружаем Apache:
systemctl reload httpd
Теперь необходимо сообщить nginx BrainyCP, что реальный IP пользователя передаётся через заголовок X-Forwarded-For .
Создаём файл:
nano /usr/local/brainycp/src/compiled/nginxb/conf.d/realip.conf
Добавляем:
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Проверяем nginx:
/usr/sbin/nginxb -t
Если ошибок нет, применяем настройки:
/usr/sbin/nginxb -s reload
BrainyCP использует собственный PHP-FPM, поэтому сначала определяем доступные службы:
systemctl list-units --type=service --all | grep -Ei 'brainy.*php|php.*brainy'
В нашем случае были обнаружены:
brainyphp-fpm.service
brainyphp8-fpm.service
Поскольку панель работает на PHP 8, используется:
brainyphp8-fpm.service
Основной конфигурационный файл PHP-FPM:
/usr/local/brainycp/src/compiled/php8/php-fpm.conf
Конфигурация пула PHP-FPM, используемого панелью:
/usr/local/brainycp/src/compiled/php8/php-fpm.d/brainy.conf
Проверить текущие настройки пула можно командой:
grep -n "^[brainy.conf]\|session.name\|php_admin_value\|php_value" \
/usr/local/brainycp/src/compiled/php8/php-fpm.d/brainy.conf
Если session.name отсутствует, PHP использует стандартное имя сессии:
PHPSESSID
Стандартное имя PHP-сессии — PHPSESSID . Если несколько сайтов используют один основной домен или общий cookie domain, браузер может хранить несколько cookies с одинаковым именем.
Например:
PHPSESSID
Domain: .example.com
Path: /
и:
PHPSESSID
Domain: panel.example.com
Path: /
В результате BrainyCP может получить неправильный идентификатор сессии.
Один из характерных симптомов — после успешной отправки формы авторизации панель снова показывает страницу входа.
Менять имя сессии глобально для всех сайтов не нужно.
Правильнее задать отдельное имя только для PHP-FPM пула BrainyCP:
BRAINYSESSID
Открываем конфигурацию:
nano /usr/local/brainycp/src/compiled/php8/php-fpm.d/brainy.conf
После строки:
php_admin_value[error_log] = /var/log/brainyphp-fpm/www-error.log
добавляем:
php_admin_value[session.name] = BRAINYSESSID
В итоге соответствующий фрагмент должен выглядеть так:
php_admin_value[error_log] = /var/log/brainyphp-fpm/www-error.log
php_admin_value[session.name] = BRAINYSESSID
Добавить строку можно также одной командой:
sed -i '/^php_admin_value[error_log]/a php_admin_value[session.name] = BRAINYSESSID' \
/usr/local/brainycp/src/compiled/php8/php-fpm.d/brainy.conf
Проверяем результат:
grep -n "session.name\|error_log" \
/usr/local/brainycp/src/compiled/php8/php-fpm.d/brainy.conf
Перед перезапуском PHP-FPM обязательно проверяем конфигурацию.
В нашей установке бинарник PHP-FPM находится здесь:
/usr/local/brainycp/src/compiled/php8/bin/php-fpm
Проверка:
/usr/local/brainycp/src/compiled/php8/bin/php-fpm \
-t \
-y /usr/local/brainycp/src/compiled/php8/php-fpm.conf
При успешной проверке появляется сообщение:
NOTICE: configuration file /usr/local/brainycp/src/compiled/php8/php-fpm.conf test is successful
Если проверка завершилась ошибкой, PHP-FPM перезапускать не следует — сначала необходимо исправить конфигурацию.
После успешной проверки перезапускаем только PHP-FPM BrainyCP:
systemctl restart brainyphp8-fpm
Другие PHP-FPM сайтов при этом перезапускать не требуется.
Проверяем состояние службы:
systemctl status brainyphp8-fpm --no-pager
Нас интересует строка:
Active: active (running)
Теперь открываем панель:
https://panel.example.com
В инструментах разработчика браузера открываем раздел Cookies.
Для BrainyCP должна появиться cookie:
BRAINYSESSID
При этом обычные сайты продолжают использовать:
PHPSESSID
Таким образом, сессия панели полностью отделена от сессий сайтов.
Если до исправления проблемы браузер уже получил старую cookie PHPSESSID для панели, её можно удалить для домена панели.
Например, удалить старую cookie для:
panel.example.com
После этого снова открыть страницу входа и авторизоваться.
Удалять cookies всех сайтов сервера необязательно.
После завершения настройки должна получиться следующая схема:
Сайты:
PHPSESSID
BrainyCP:
BRAINYSESSID
При этом:
dig +short panel.example.com
httpd -t
systemctl reload httpd
/usr/sbin/nginxb -t
/usr/sbin/nginxb -s reload
systemctl list-units --type=service --all | grep -Ei 'brainy.*php|php.*brainy'
/usr/local/brainycp/src/compiled/php8/bin/php-fpm \
-t \
-y /usr/local/brainycp/src/compiled/php8/php-fpm.conf
systemctl restart brainyphp8-fpm
systemctl status brainyphp8-fpm --no-pager
tail -50 /var/log/brainyphp-fpm/www-error.log
tail -50 /var/log/httpd/panel.example.com-error.log
Если BrainyCP нормально работает при входе по IP-адресу, но после переноса на поддомен перестаёт сохранять авторизацию, одной из причин может быть конфликт PHP-сессий.
Вместо изменения исходного кода BrainyCP или отключения проверки IP и авторизации проблему можно решить на уровне PHP-FPM.
Основная настройка заключается всего в одной строке:
php_admin_value[session.name] = BRAINYSESSID
После перезапуска:
systemctl restart brainyphp8-fpm
BrainyCP начинает использовать отдельную cookie BRAINYSESSID , тогда как остальные сайты сервера продолжают работать со стандартной PHPSESSID .
Такой вариант позволяет изолировать сессию панели от сессий сайтов и избежать конфликтов при размещении BrainyCP на отдельном поддомене.