Что такое обратный прокси Nginx: краткий ответ
Обратный прокси-сервер Nginx принимает HTTP- или HTTPS-запросы от внешних клиентов, выбирает целевой upstream и передает запрос веб-приложению, API или другому backend-сервису. Клиент обращается к публичному адресу Nginx, а внутреннее приложение может работать в приватной сети и не принимать подключения из интернета напрямую.
Типовая последовательность выглядит так: клиент -> Nginx -> upstream/backend -> Nginx -> клиент. Nginx получает запрос, применяет правила маршрутизации и доступа, отправляет его нужному сервису, принимает ответ и возвращает его клиенту.
Такой слой добавляют для единой точки входа, маршрутизации запросов, TLS-терминации, балансировки нагрузки, кеширования и централизованных политик доступа. Nginx можно поставить перед одним приложением, группой API-сервисов, несколькими экземплярами backend или кластером Kubernetes.
Как проходит запрос через Nginx и upstream
В конфигурации Nginx термин upstream обозначает целевой сервер или группу серверов, которым прокси передает запросы. Backend выполняет бизнес-логику: обрабатывает API-вызов, формирует HTML, обращается к базе данных или запускает другую операцию.
- Клиент устанавливает соединение с публичным IP-адресом и портом Nginx.
- Nginx выбирает блок
serverпо домену, а затем подходящийlocationпо URI. - Директива
proxy_passпередает запрос upstream-сервису. - Backend формирует ответ и отправляет его обратно Nginx.
- Nginx возвращает ответ клиенту и записывает сведения о запросе в журнал.
Для клиента публичной точкой входа остается Nginx. Внутренний сервис может слушать 127.0.0.1:8080, адрес приватной сети или порт Kubernetes Service. Такая схема снижает количество открытых наружу портов и позволяет менять внутренний backend без изменения DNS-имени, которым пользуются клиенты.
Прокси-сервер и обратный прокси: в чем разница
Обычный прокси, или forward proxy, работает на стороне клиента. Обратный прокси, или reverse proxy, находится перед серверной инфраструктурой. Оба решения принимают соединения от одной стороны и устанавливают соединение с другой, но защищают разные участки системы.
Обычный proxy работает на стороне клиента
При использовании обычного прокси рабочая станция, браузер или приложение отправляет исходящий трафик через промежуточный сервер. Прокси подключается к внешнему сайту от своего имени, поэтому сайт обычно видит адрес прокси, а не адрес конкретной рабочей станции.
Forward proxy применяют для контроля исходящего доступа, фильтрации доменов, ведения журналов, ограничения категорий трафика и организации централизованного выхода в интернет. Инициатором запроса остается клиент, который настроен использовать прокси.
Reverse proxy работает перед приложениями и API
В схеме с Nginx клиент не настраивает прокси вручную. Он обращается к домену приложения, а DNS указывает на Nginx или внешний балансировщик перед ним. Nginx сам устанавливает соединение с backend и скрывает внутреннюю топологию от внешнего пользователя.
Приложение может не иметь публичного IP-адреса и не принимать TLS-соединения самостоятельно. Nginx выносит на свой уровень часть сетевых задач: выбор сервиса, прием HTTPS, ограничение запросов, логирование и распределение нагрузки.
| Признак | Обычный proxy | Обратный proxy |
|---|---|---|
| Кто использует прокси | Браузер, рабочая станция или клиентское приложение | Внешний клиент обращается к публичному адресу, а Nginx подключается к backend |
| Направление трафика | Исходящий трафик клиента | Входящий трафик к приложению или API |
| Чей адрес скрывается | Адрес клиента скрывается от внешнего сервера | Адреса и структура backend скрываются от внешнего клиента |
| Типовые задачи | Фильтрация выхода в интернет, контроль доступа, журналы | Маршрутизация, TLS, балансировка, кеширование, защита приложения |
| Размещение | Перед клиентскими устройствами | Перед веб-приложением, API или группой сервисов |
Типовая схема: Nginx перед веб-приложением и API
В простом production-контуре DNS направляет домен на Nginx. Публичный HTTPS-трафик приходит на него, а внутренние маршруты проксируются в разные сервисы. Например, главная страница может обслуживаться frontend-приложением, API находится за путем /api/, а административная панель работает за путем /admin/.
Маршрутизация запросов по host и URI
Nginx выбирает backend по доменному имени и пути запроса. Один сервер может обслуживать несколько независимых приложений:
api.example.comнаправляется в API-сервис на порту8080.app.example.comнаправляется в веб-приложение на порту3000.example.com/api/направляется в API, аexample.com/обслуживает frontend или монолит.example.com/admin/направляется в отдельный административный сервис с более строгими правилами доступа.
Для каждого server и location задают собственные таймауты, лимиты, правила аутентификации и параметры проксирования. В Kubernetes похожую функцию выполняет NGINX Ingress Controller: он принимает трафик на ingress-краю, выбирает Service по host и URI и применяет политики до передачи запроса в контейнер приложения.
Почему backend не стоит публиковать напрямую
Прямой доступ к каждому backend усложняет контроль периметра. Для каждого сервиса приходится отдельно настраивать сертификаты, открытые порты, журналы, ограничения запросов и правила доступа. Ошибка в одном сервисе может открыть наружу административный интерфейс или внутренний API.
Nginx дает единую точку для таких правил. Backend можно оставить в приватной подсети, разрешив входящие соединения только от адреса Nginx. Это не заменяет firewall: сетевые правила должны отдельно ограничивать источники, порты и направления трафика.
Единая точка входа упрощает смену backend. Публичный домен и клиентский URL сохраняются, а внутренний адрес можно изменить в конфигурации Nginx. Централизованные логи помогают сопоставить внешний запрос с ответом конкретного сервиса.
Зачем нужен обратный прокси: основные задачи Nginx
Reverse proxy выносит сетевые функции перед приложением. Каждая функция требует собственной политики: балансировка зависит от состояния backend, TLS от модели доверия, кеширование от актуальности данных, а контроль доступа от типа маршрута.
Балансировка нагрузки Nginx между backend-серверами
Nginx может распределять запросы между несколькими экземплярами одного приложения. Публичный endpoint остается общим, а upstream содержит список внутренних узлов.
upstream app_pool {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
server 10.0.0.13:8080;
}
По умолчанию Nginx использует распределение запросов по принципу round-robin. Для приложений с разной длительностью запросов может подойти least_conn, который направляет новый запрос на сервер с меньшим числом активных соединений. ip_hash помогает сохранять привязку клиента к одному узлу, но уменьшает равномерность распределения и не заменяет хранилище общих сессий.
Группа upstream снижает зависимость от одного экземпляра и позволяет масштабировать приложение горизонтально. Стратегию балансировки выбирают по поведению API, размеру запросов, наличию WebSocket, состоянию сессий и требованиям к отказоустойчивости.
Пассивные проверки фиксируют ошибки соединения и ответов во время реального трафика. Активные health checks зависят от редакции Nginx и используемых компонентов. Одного факта наличия нескольких строк server недостаточно для полноценной проверки готовности приложения: backend может принимать TCP-соединение и при этом возвращать ошибку на рабочий endpoint.
TLS-терминация на уровне reverse proxy
При TLS-терминации Nginx принимает HTTPS-соединение, использует сертификат домена и расшифровывает запрос. Внутренний backend получает уже обработанное HTTP-соединение или новое HTTPS-соединение, если шифрование требуется на всем пути.
Централизация TLS уменьшает число мест, где хранятся сертификаты и задаются параметры протоколов. Обновление сертификата и настройка поддерживаемых версий TLS проходят на ingress-узле, а приложения сохраняют единый способ обработки обычных HTTP-запросов.
Передача HTTP после TLS допустима только по контролируемой доверенной сети. Для внешнего приложения нужно передать исходную схему через X-Forwarded-Proto, иначе оно может считать запрос HTTP и сформировать неправильный URL или бесконечный редирект на HTTPS. Доступ к внутреннему сегменту ограничивают firewall и правилами сети.
Кеширование ответов и разгрузка приложения
Proxy cache подходит для повторяющихся публичных GET-ответов. Типичные кандидаты: статические файлы, редко меняющиеся страницы, публичные каталоги и API-ответы с четко заданным сроком актуальности.
Кеширование снижает число обращений к backend и уменьшает задержку для повторных запросов. Эффект зависит от доли одинаковых запросов, размера ответа, TTL и корректности cache key.
Персонализированные ответы, запросы с авторизацией и данные с высокой потребностью в актуальности нельзя кешировать без явных правил. До настройки proxy cache определяют:
- какие методы и пути разрешено сохранять;
- как учитываются query-параметры, cookies и заголовки;
- какой TTL действует для разных типов ответа;
- как приложение задает
Cache-Control; - как очищать кеш после публикации или изменения данных.
Ошибка в cache key может привести к выдаче одному пользователю ответа другого пользователя. Для API с персональными данными безопаснее отключить кеш или явно исключить запросы с заголовком Authorization и сессионными cookies.
Централизованные политики перед приложением
Nginx может проверять доступ до передачи запроса backend. На этом уровне задают базовую аутентификацию, списки разрешенных адресов, ограничение частоты запросов через limit_req, лимит размера тела запроса и единое журналирование.
В Kubernetes NGINX Ingress Controller позволяет прикреплять правила к конкретному ingress-маршруту. Например, один путь можно отправить в OAuth2-поток, другой закрыть Basic Auth для CI-webhook, а третий оставить публичным. При использовании ExternalAuth Policy запрос сначала проходит проверку auth-сервисом и не попадает в контейнер приложения при отказе.
Общие политики сокращают дублирование в микросервисах. При этом Nginx не заменяет авторизацию внутри приложения: backend по-прежнему должен проверять права на операцию и корректность данных.
Минимальная настройка Nginx как обратного прокси
Минимальная схема состоит из upstream или адреса backend, блока server, маршрута location и директивы proxy_pass. Перед изменением рабочей конфигурации сохраните текущий вариант и проверьте синтаксис командой nginx -t.
Блок upstream и директива proxy_pass
Для одного локального приложения подойдет такой server-блок:
upstream app_backend {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
upstream app_backend задает логическое имя целевого сервиса. proxy_pass передает ему запрос. Директива proxy_set_header формирует заголовки, которые сохраняют имя хоста, адрес клиента, цепочку прокси и исходную схему соединения.
Для двух экземпляров приложения меняется только содержимое upstream:
upstream app_backend {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
Остальной маршрут может остаться прежним. Такой подход упрощает замену адресов и добавление новых backend. Перед использованием проверьте, что Nginx может установить соединение с каждым узлом, а приложение слушает нужный интерфейс и порт.
Конфигурация выше принимает HTTP на порту 80. Для публичного HTTPS добавляют отдельный сервер на 443, сертификат и закрытый ключ, а затем перенаправляют HTTP на HTTPS или закрывают порт 80 согласно политике домена. Пути к сертификатам, адреса upstream, firewall и параметры TLS всегда зависят от конкретной среды.
Заголовки, таймауты и особенности API
Host помогает приложению определить исходный домен. X-Real-IP передает адрес непосредственного клиента для простых сценариев. X-Forwarded-For хранит цепочку адресов, если запрос прошел через несколько доверенных прокси. X-Forwarded-Proto сообщает, использовал ли клиент HTTP или HTTPS на внешнем соединении.
Таймауты выбирают по реальному поведению API. proxy_connect_timeout ограничивает время установки соединения с backend, proxy_read_timeout определяет допустимую паузу при чтении ответа, а proxy_send_timeout ограничивает передачу запроса в backend.
location /api/ {
proxy_pass http://app_backend;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Слишком короткий proxy_read_timeout обрывает долгие отчеты, загрузки и операции с медленной базой. Слишком большое значение удерживает соединения при зависшем backend. Настройку проверяют по метрикам и журналам, а не выбирают случайным числом.
WebSocket и другие upgrade-соединения требуют передачи специальных заголовков:
location /socket/ {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Host $host;
}
Такой блок применяют к маршрутам, которым действительно нужен upgrade. Для обычного API эти заголовки не требуются. При загрузке файлов отдельно проверяют client_max_body_size, а при потоковой выдаче и server-sent events учитывают буферизацию и длительность соединения.
Исходный IP клиента: X-Forwarded-For и PROXY protocol
После появления прокси backend обычно видит адрес Nginx, потому что именно Nginx устанавливает сетевое соединение с приложением. Это влияет на аудит, rate limiting, списки доступа, геолокацию и расследование инцидентов. Для приложения адрес клиента нужно передать отдельным механизмом.
Передача адреса клиента через HTTP-заголовки
Для HTTP-приложений чаще всего используют X-Real-IP и X-Forwarded-For. В минимальной конфигурации Nginx можно передать непосредственный адрес так:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
Если перед Nginx уже стоит доверенный балансировщик, цепочку сохраняют через $proxy_add_x_forwarded_for. Внешний клиент способен самостоятельно прислать заголовок X-Forwarded-For, поэтому на границе доверенной сети его очищают или заменяют, а не принимают без проверки.
Приложение и его веб-сервер должны знать список доверенных прокси. Без этого злоумышленник сможет подменить IP для обхода ограничений или скрыть источник запроса в журнале. Правило доверия задают отдельно для каждого ingress-узла и сетевого сегмента.
Когда нужен PROXY protocol v2
PROXY protocol v2 передает исходные данные соединения от прокси к backend на уровне подключения. В служебном заголовке могут находиться адрес и порт клиента, адрес и порт назначения, а также дополнительные TLV-метаданные. Механизм полезен для TCP-сервисов, специальных балансировщиков и схем, где HTTP-заголовков недостаточно.
PROXY protocol v2 и X-Forwarded-For решают разные задачи. Первый передает сведения о сетевом соединении до разбора прикладного протокола, второй передает клиентский контекст внутри HTTP-запроса.
Поддержка должна быть согласована на обеих сторонах: прокси отправляет PROXY-заголовок, а backend ожидает и разбирает его. Включение протокола только на одной стороне приводит к ошибкам разбора, ответам 400 или невозможности установить соединение. Перед настройкой проверяют документацию конкретного backend и тип транспорта, HTTP или TCP.
Когда использовать Nginx reverse proxy и что проверить перед внедрением
Nginx подходит, когда внешний HTTP(S)-трафик нужно направить к одному или нескольким внутренним сервисам, применить общие правила доступа, завершить TLS, распределить нагрузку или скрыть backend от прямого подключения. Для одного небольшого сервиса прокси добавляет отдельный компонент, поэтому его ценность оценивают по требованиям к сертификатам, логам, маршрутизации и масштабированию.
Сценарии, в которых Nginx перед API особенно полезен
- Один API за HTTPS. Nginx принимает TLS, передает приложению исходную схему и закрывает прямой доступ к порту API.
- Frontend и API на одном домене. Запросы к
/идут в frontend, а запросы к/api/направляются в API без отдельных публичных доменов. - Несколько микросервисов. Разные host или URI ведут к отдельным сервисам, для маршрутов задаются собственные лимиты и проверки.
- Несколько экземпляров backend. Upstream распределяет запросы между узлами и позволяет выводить отдельный экземпляр из трафика.
- Kubernetes ingress. NGINX Ingress Controller принимает внешний трафик перед Service и применяет ingress-политики до обращения к контейнеру.
Для тестового контура или production-развертывания Nginx можно разместить на VDS, а backend и базы данных держать в отдельных сетевых сегментах. Облачная инфраструктура с серверами, хранилищем и Kubernetes доступна у Timeweb Cloud. Конкретную схему выбирают по нагрузке, требованиям к отказоустойчивости и модели доступа.
Проверки после настройки
- Проверьте синтаксис командой
nginx -t. Ошибки в директивах нужно исправить до перезагрузки сервиса. - Выполните плавную перезагрузку через
systemctl reload nginxи убедитесь, что старые соединения завершаются корректно. - Проверьте публичный endpoint с HTTP-клиентом: статус ответа, заголовки, тело, редирект на HTTPS и время отклика.
- Проверьте маршрут до каждого upstream отдельно. Убедитесь, что DNS, firewall, security groups и локальные правила разрешают соединение Nginx с backend.
- Подтвердите, что приложение получает правильную схему в
X-Forwarded-Protoи не создает циклический редирект. - Сверьте IP клиента в логах Nginx и приложения. Проверьте настройку доверенных прокси и возможность подмены forwarded-заголовков.
- Остановите один backend и убедитесь, что запросы получают корректную обработку отказа, а рабочие узлы продолжают принимать трафик.
- Проверьте сертификаты, срок их действия, лимит тела запроса, таймауты, ограничения частоты, кеширование и поведение долгих API-операций.
- Настройте мониторинг кодов 4xx и 5xx, времени ответа, числа активных соединений и состояния upstream. Конфигурацию проверяйте в тестовой среде или в контролируемое окно изменений.
Для перехода к конкретным задачам пригодятся архитектурный разбор обратного прокси, пошаговая настройка Nginx, подборка готовых конфигураций для типовых задач и руководство по маршрутизации микросервисов через location и proxy_pass.