Андрей Смирнов
Время чтения: ~6 мин.
Просмотров: 5

Nginx как Reverse Proxy для сайта, использующего SSL

Мануал 

Что такое обратный прокси?

Прокси-сервер действует как посредник между клиентом и другим сервером.

Он получает ресурсы с сервера, к которому вы хотите подключиться, и отправляет его вам для просмотра. Обратный прокси-сервер работает так же, за исключением того, что роль меняется на противоположную.

Когда вы запрашиваете информацию с сервера, обратный прокси-сервер получает запрос и отправляет его на соответствующий внутренний сервер.

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

Теперь давайте сделаем более общий вариант настройки ?

reverse-proxy-illustration1-300x116.png

Преимущества обратного прокси

В зависимости от вашего приложения у вас могут быть разные варианты использования обратного прокси.

  • Обратный прокси-сервер позволяет запускать несколько приложений на одном сервере. Если на одном сервере запущено несколько приложений, все они не могут одновременно прослушивать порт 80 или 433. Обратный прокси-сервер позволяет настроить обратный прокси-сервер так, чтобы при необходимости перенаправлять трафик отдельным приложениям.
  • Балансировка нагрузки — если у вас несколько серверов, на которых запущено одно приложение, вы можете использовать обратный прокси-сервер для равномерного распределения трафика на каждом сервере.
  • Брандмауэр веб-приложений — вы можете использовать обратный прокси-сервер, чтобы скрыть свое приложение от общественности, а также отфильтровать спам-IP или защитить от DDOS-атаки.

Настройка Nginx в качестве обратного прокси

Для начала стоит сказать, что можно воспользоваться услугами прокси, не настраивая все самому.

Представлено очень большое количество решений, среди которых можно выделить https://youproxy.ru/russian-proxy, не зависимо от целей, которые вы преследуете, используя прокси-сервера.

Чтобы настроить Nginx в качестве обратного прокси-сервера, мы будем использовать параметр proxy_pass в файлах конфигурации Nginx.

Примечание. В этом руководстве предполагается, что вы немного знакомы с Nginx и уже установили и настроили Nginx на своем сервере.

В большинстве случаев Nginx будет внешним сервером, прослушивающим порт 80 (HTTP) или 443 (HTTPS) для входящих запросов.

Поскольку может быть только одна служба, прослушивающая порт 80 или 443, ваше приложение должно будет прослушивать другой порт, например порт 8081.

Самая простая конфигурация будет выглядеть примерно так:

server {    listen 80;    listen [::]:80;       server_name myapp.com;       location / {        proxy_pass http://localhost:8081/;    }  }

Это означает, что все входящие запросы на myapp.com через порт 80 будут перенаправлены на порт 8081.

Дополнительные настройки

Помимо директивы proxy_pass, есть несколько других директив, которые вы можете использовать для более сложной настройки.

proxy_set_header — позволяет установить заголовок для отправки в фоновое приложение.

Например, посмотрите следующую конфигурацию:

proxy_set_header        Host            $host;  proxy_set_header        X-Real-IP       $remote_addr;  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

Вы можете установить необходимый заголовок прокси-сервера для передачи приложению, чтобы оно знало IP-адрес и удаленный адрес запроса и выводило правильное содержимое для сайта запроса.

proxy timeout — позволяет установить значение тайм-аута для отправки и получения прокси-запросов.

Например:

proxy_connect_timeout   90;  proxy_send_timeout      90;  proxy_read_timeout      90;

proxy_buffers — это позволяет Nginx временно хранить ответ прокси-сервера и отправлять его на сервер запросов только после того, как прокси-сервер завершит ответ.

Например:

proxy_buffers           32 4k;

Если ваше приложение отправляет большой кусок файла, то вы можете отключить proxy_buffers:

proxy_buffering     off;

Резюме

Как видите, Nginx — это полноценный обратный прокси-сервер

Самое приятное в нем то, что его конфигурация проста, проста в использовании и все же позволяет масштабироваться для более сложных сценариев.

Для получения более подробной информации вы можете ознакомиться с документацией по прокси-модулю Nginx или примерами конфигурации.

Введение

Как настроить nginx в качестве frontend к apache и зачем это нужно — написано неоднократно, в том числе и на Хабре. Мой случай немного отличается от классического. Начиналось все как обычно, проект на apache, увеличение количества посетителей и, связанная с ним, недостаточность ресурсов сервера. Но проект использовал SSL для защиты обмена данными с клиентами. С чем я столкнулся и как решил проблемы я расскажу под катом.

Проблемы

Поскольку непосредственный прием запросов клиентов перешел на плечи nginx то и работу с SSL надо переносить на него же. Apache, который теперь висел но loopback 127.0.0.1:8080, в поддержке SSL не нуждался. Первая проблемка заключалась в том, что сертификат был от Thawte, а они требовали использования промежуточного сертификата. Nginx для работы с такими сертификатами не имеет специальной директивы. В конфиге apache было так:

<virtualhost>   ...   SSLEngine on    SSLCertificateFile /usr/local/ssl/www.blabla.ru/public.crt   SSLCertificateKeyFile /usr/local/ssl/www.blabla.ru/private.key   SSLCACertificateFile /usr/local/ssl/www.blabla.ru/intermediate.crt   ... </virtualhost>

Как быть с SSLCACertificateFile в nginx? Оказалось надо просто «срастить» два файла, поместив их содержимое в один (публичный сертификат, следом промежуточный):

cd /usr/local/ssl/www.blabla.ru cp public.crt public_concat.crt cat intermediate.crt >> public_concat.crt 

Все, теперь в nginx просто пишем:

    server {         listen                  1.2.3.4:443;         server_name             www.blabla.ru;          ssl                     on;         ssl_certificate         /usr/local/ssl/www.blabla.ru/public_concat.crt;         ssl_certificate_key     /usr/local/ssl/www.blabla.ru/private.key;         ...     } 

Редирект с незащищенного сайта на защищенный сложностей в настройке не вызвал:

    server {         listen          1.2.3.4:80;         server_name     www.blabla.ru blabla.ru;         # rewrite ^(.*) https://www.blabla.ru$1 permanent;         return 301 https://www.blabla.ru$request_uri;     } 

Сложности начались при работе ajax. Асинхронные запросы к серверу выполнялись с префиксом http:// что вызывало губительный для ajax редирект 301. Появилась необходимость передавать переменные окружения, в частности имя протокола, из nginx в apache, сделано это было так: в nginx:

    server {         ...         location / {             ...             proxy_set_header            X-Forwarded-Proto $scheme;             ...         }         ...     } 

Самое главное в apache надо в определении виртуального хоста прописать:

<virtualhost>   ServerName www.blabla.ru   ...   SetEnvIf X-Forwarded-Proto https HTTPS=on   ... </virtualhost>

Теперь все ajax запросы идут на https:// что и требовалось. Для этого трюка модуль apache setenvif_module должен быть установлен и включен в конфиге:

LoadModule setenvif_module libexec/apache22/mod_setenvif.so 

Также стоит иметь ввиду что некоторые приложения могут сами определять свой путь по переменным окружения. Так например phpMyAdmin, так нужный разработчикам ресурса, в случае если у него в конфиге не указан полный путь будет формировать его сам с указанием порта. Так получалось у меня нечто вида:

https://www.blabla.ru:80/myadmin 

Вот это самое :80 сильно все портило, phpMyAdmin не открывался с руганью что ошибка защиты SSL. Вылечилось, как указано выше, прямым указанием пути в конфиге phpMyAdmin-а:

$cfg['PmaAbsoluteUri'] = 'https://www.blabla.ru/myadmin'; 

Еще не стоит забывать о передаче реальных IP адресов посетителей в apache для сохранения имеющейся схемы ведения логов. Это расписано неоднократно, копайте в сторону модуля apache rpaf_module. PS: Все делалось под FreeBSD 8.2, Apache 2.2.22_5, nginx-1.0.14,1. Полные тексты конфигов не выкладывал чтобы не раздувать заметку. По этой же причине на заострялся на передаче реальных IP клиентов и модуле rpaf_module. Если потребуется — выложу.Используемые источники:

  • https://itsecforu.ru/2019/03/26/как-использовать-nginx-в-качестве-обрат/
  • https://habr.com/post/142363/

Рейтинг автора
5
Подборку подготовил
Максим Уваров
Наш эксперт
Написано статей
171
Ссылка на основную публикацию
Похожие публикации