Nginx reverse-proxy для Bitrix VM

В данной статье я расскажу про опыт настройки nginx в качестве прокси-сервера на виртуальную машину битрикс с редиректом на https. В процессе настройки возникали разного рода ошибки, основная проблема была в том, что при перенаправлении с http на https и обращении к domain.ru/bitrix без слэша в конце, в URL подставлялся 443 и протокол менялся на http. Получалась запись вида https://domain.ru/bitrix -> http://domain.ru:443/bitrix/ и в итоге ошибка 400 Bad Request, The plain HTTP request was sent to HTTPS port. Также не работал модуль Push&Pull после установки из menu.sh необходимого модуля и подключении его в настройке самого модуля из админки (bitrix vm 7.3.3+).

Конфиг прокси-сервера Nginx:

server {
        server_name {DOMAIN};
#       access_log /var/log/nginx/{DOMAIN}.access.log;
        listen 80;
        return 301 https://$host$request_uri;
}

server {
        listen 443 ssl http2;
        server_name {DOMAIN};
        ssl_certificate "/etc/nginx/ssl/cert.crt";
        ssl_certificate_key "/etc/nginx/ssl/key.key";
        ssl_prefer_server_ciphers on;

        access_log /var/log/nginx/{DOMAIN}.access.log;

        location / {
                proxy_ignore_client_abort on;
                proxy_pass http://{NODE-IP}:80;
                proxy_redirect http://{NODE-IP}:80 /;
                proxy_read_timeout 300;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Port $server_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header HTTPS YES;
                
                # for Push&Pull
                location /bitrix/subws {
                proxy_pass http://{NODE-IP}:80;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_redirect http://{NODE-IP}:80 /;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Port $server_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header HTTPS YES;
                }
        }
        
### Push&Pull ###
#################

server {
listen 8894 ssl http2;
        server_name {DOMAIN};
        ssl_certificate  /etc/pki/tls/certs/fondgkh.crt;
        ssl_certificate_key  /etc/pki/tls/certs/fondgkh.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

# proxy
        location / {
        proxy_pass http://{NODE-IP}:8893;
        proxy_redirect http://{NODE-IP}:8893 /;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header HTTPS YES;
        }
}

Именно в такой конфигурации все заголовки корректно проксируются и не вызывают ошибок. Конфиг сделан с учётом рекомендаций Mozilla SSL Configuration Generator, бездумно копировать не стоит.

Важно настроить location /bitrix/subws, где проксируются заголовки Upgrade $http_upgrade, Connection “upgrade” и прослушивание 8894 порта для работы Push&Pull и мобильного приложения на порту 8893 на конечном сервере, где установлен Push-Server.

На прокси-сервере должны быть открыты следующие TCP-порты для корректной работы Push&Pull и мобильного приложения:

-A INPUT -p tcp -m multiport --dports 80,443,8893,8894,8895 -j ACCEPT

В самой виртуалке с битрой по умолчанию я изменил только конфиг nginx, отвечающий за http раздел:

/etc/nginx/bx/site_avaliable/bx_ext_....conf

Было: proxy_set_header      Host $host:80;
Стало: proxy_set_header      Host $host; 

После этого restart или reload nginx на обоих серверах и можно проверять.

upd Возникла ситуация, в которой виртуальную машину с битрикс поместили за Citrix Netscaler, вылезли проблемы с заголовками при проксировании. Как и ранее, в конфиге был убран порт у заголовка Host, но в таком случае некоторые страницы, где возникали проблемы, вообще не загружались. Долго разбираться не стал, в чем проблема: то ли на стороне Citrix, то ли в nginx, поэтому сразу обратился в тех.поддержку Bitrix и вот их ответ: конфиги nginx править не надо (ну, точнее надо, но по их версии проще вставить код), только заголовки через php в файле dbconn.php:

if (($pos = strpos($_SERVER['HTTP_HOST'], ':')) !== false)
{
$HTTP_HOST = $_SERVER['HTTP_HOST'] = substr($_SERVER['HTTP_HOST'],0,$pos);
}

$_SERVER["HTTPS"] = "On";
$_SERVER['SERVER_PORT'] = 443;

Если же нужно поправить более правильным вариантом , то в httpd:

<IfModule setenvif_module>
    SetEnvIf X-Forwarded-Proto https HTTPS=on
</IfModule>

А в nginx на виртуальной машине Bitrix в /etc/nginx/bx/site_avaliable/ssl.s1.conf :

error_page 497 https://$host:$server_port$request_uri;

Эта строка говорит веб-серверу (это работает только в случае nginx), что в случае простого HTTP-запроса на порт HTTPS нужно перенаправлять пользователя на “правильный” адрес. Правильный адрес состоит из указания корректного протокола HTTPS, хостнейма сервера, порта и оставшейся части ссылки из “неправильного” запроса.

Теперь значение из переменной $_SERVER[‘HTTPS’] не пустое и апач знает, что клиент изначально пришёл по https.

Резюме: в общем, вариантов решения я перечислил несколько, кому-то подходит, кому-то – нет, но всегда интереснее докопаться до истины . Основными причинами является то, что переменная $_SERVER[‘HTTPS’] пустая, а также где-то встречал рекомендацию не разворачивать сайты в директории /home/bitrix/www, т.к. в конфиге апача bx/conf/default.conf не формируется строка вида ServerName <domain_name>, поэтому лучше всегда размещать сайты в виртуальной машине битрикса по пути, отличному от штатного /home/bitrix/www.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *