Руководства

Что такое nginx и обратный прокси (reverse proxy)

«nginx это» чаще всего обратный прокси: сервер, который принимает запросы и передаёт их нужному приложению. Как это работает и какие заголовки добавляет.

Опубликовано ~9 мин чтения

Короткий ответ: «nginx это» — веб-сервер, который на практике чаще всего работает как обратный прокси (reverse proxy): сервер, который стоит перед одним или несколькими веб-серверами и принимает каждый запрос, предназначенный им. Он решает, какой backend обработает запрос, передаёт его туда и отдаёт ответ посетителю, который общается только с самим прокси. По пути обратный прокси обычно обрабатывает HTTPS, распределяет нагрузку между backend-серверами, кеширует, сжимает и фильтрует трафик. Nginx, HAProxy, Caddy и Traefik — распространённые обратные прокси; Cloudflare — такой же прокси, который можно арендовать.

«Обратный» — в противоположность обычному прокси-серверу (forward proxy), который работает для клиентов и прячет их. Обратный прокси работает для серверов и прячет их: посетитель видит один адрес и один сертификат, что бы за ним ни работало.

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

Проследим один запрос к https://example.com/api/orders:

  • DNS направляет example.com на IP-адрес обратного прокси, а не на само приложение.
  • Браузер открывает TLS-соединение с прокси, который предъявляет сертификат и расшифровывает запрос.
  • Прокси сопоставляет имя хоста и путь со своими правилами — /api/ идёт в API-сервис на 127.0.0.1:8000, всё остальное — на фронтенд на порту 3000.
  • Он открывает собственное соединение к этому backend, обычно по обычному HTTP на localhost или приватной сети, и передаёт запрос с заголовками, которые сохраняют настоящего клиента и схему.
  • Backend отвечает прокси; прокси может сжать или закешировать ответ, затем отправляет его браузеру через TLS-соединение.

Соединений два отдельных, и backend никогда не видит посетителя напрямую. Именно этот факт объясняет и преимущества, и почти все баги обратных прокси.

Для чего нужен обратный прокси?

ЗадачаЧто делаетПочему это помогает
Терминация TLSДержит сертификаты и говорит с посетителями по HTTPSОдно место для сертификатов и их продления; приложения остаются на обычном HTTP
МаршрутизацияНаправляет запросы на backend по имени хоста или путиМного сайтов и сервисов на одном IP-адресе и порту 443
Балансировка нагрузкиРаспределяет запросы между несколькими backend, пропускает упавшиеБольше пропускной способности, перезапуск без простоя
КешированиеХранит ответы и сам отвечает на повторыМеньше работы приложению, быстрее ответы
Сжатиеgzip или Brotli для текстовых ответовМеньше байт в канале
ЗащитаОграничение частоты запросов, лимиты размера, правила по IP, WAFЗлоупотребления останавливаются раньше, чем доходят до приложения
Скрытие backendИз интернета доступен только проксиМеньше поверхность атаки, backend можно свободно переносить

На одном сервере самая частая причина — вторая строка таблицы. У VPS один публичный IP-адрес и один порт 443, а вам нужны блог, API, дашборд и самостоятельно установленное приложение на нём. Каждое приложение слушает свой локальный порт; обратный прокси — единственное, что сидит на 443, и маршрутизирует по имени хоста.

Какие заголовки добавляет обратный прокси и почему это важно?

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

  • Host — имя хоста, которое запросил посетитель. Nginx заменяет его именем upstream, если вы не передаёте $host дальше сами.
  • X-Forwarded-For — IP-адрес клиента, с добавлением адресов более ранних прокси.
  • X-Forwarded-Proto — https или http, схема, которую использовал посетитель.
  • Forwarded — та же информация в стандартной форме (RFC 7239), приложения читают её реже, чем заголовки X-.
nginx · минимальный обратный прокси
server {
    listen 443 ssl;
    server_name app.example.com;
    # здесь — строки ssl_certificate и ssl_certificate_key

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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;
    }
}

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

Caddyfile
app.example.com {
    reverse_proxy 127.0.0.1:3000
}

Nginx, HAProxy, Caddy или Traefik?

СофтСильная сторонаКонфигурацияХорошо подходит для
NginxВеб-сервер и прокси в одном; статика, кешированиеТекстовый конфиг, reload без разрыва соединенийБольшинство настроек на одном сервере
HAProxyБалансировка нагрузки, TCP и HTTP, детальные health-check и статистикаТекстовый конфигНесколько backend, большое число соединений
CaddyАвтоматический HTTPS, короткие конфигиCaddyfile или JSON APIМаленькие серверы, быстрая настройка
TraefikСам находит сервисы Docker и Kubernetes по меткамМетки на контейнерах, динамическиХосты, где много контейнеров
Apache httpdmod_proxy рядом с уже работающими сайтами на ApacheТекстовый конфигСерверы, где уже крутится Apache

Любой из них справляется с основной задачей. Выбирайте тот, чья модель конфигурации подходит вашему способу деплоя: файлы, которые редактируют руками (Nginx, HAProxy), минимум конфигурации (Caddy), или контейнеры, которые сами о себе заявляют (Traefik).

Обратный прокси vs балансировщик нагрузки, API-gateway и CDN

  • Балансировщик нагрузки: обратный прокси, у которого основная задача — распределять нагрузку. Любой обратный прокси с более чем одним backend уже балансирует; выделенные балансировщики также умеют работать на уровне TCP (четвёртый уровень), вообще не читая HTTP.
  • API-gateway: обратный прокси для API с авторизацией, квотами, преобразованием запросов и ключами для каждого клиента сверху.
  • CDN: обратный прокси, распределённый по множеству точек, кеширующий ближе к посетителям. Разместив сайт за CDN, вы делаете CDN первым обратным прокси, а собственный — вторым.
  • Веб-сервер: Nginx и Apache — и то, и другое одновременно. Тот же процесс может сам отдавать статические файлы и проксировать динамические запросы серверу приложений.

Что идёт не так с обратными прокси?

  • 502 Bad Gateway — прокси не получил валидного ответа: backend упал, слушает другой порт или прервался посреди запроса. Причины разобраны в руководстве по 502 в nginx.
  • 504 Gateway Timeout — backend отвечал дольше, чем таймаут чтения прокси, у nginx это 60 секунд по умолчанию.
  • Циклы редиректов после включения HTTPS — приложение видит от прокси обычный HTTP и бесконечно редиректит на HTTPS. Передавайте X-Forwarded-Proto и настройте фреймворк доверять прокси.
  • У всех посетителей в логах один и тот же IP — 127.0.0.1 или адрес прокси. Причина и решение те же: заголовки переадресации плюс настройка доверенного прокси.
  • 413 Request Entity Too Large — nginx по умолчанию ограничивает тело запроса 1 МБ; поднимите client_max_body_size для загрузок.
  • WebSocket сразу отваливается — для апгрейда нужны proxy_http_version 1.1 плюс заголовки Upgrade и Connection. До версии 1.29.7 nginx по умолчанию говорил с backend по HTTP/1.0, и старые пакеты дистрибутивов до сих пор так делают.

Не дайте backend обходить прокси

Обратный прокси защищает только то, до чего нельзя добраться мимо него. Привязывайте приложения к 127.0.0.1, а не к 0.0.0.0, и проверяйте через ss -tlnp, что слушает на публичных адресах. Docker заслуживает отдельного внимания: порт, опубликованный через -p 3000:3000, открывается в iptables самим Docker, минуя правила UFW, — публикуйте его как -p 127.0.0.1:3000:3000, если достать до него должен только прокси.

Обратный прокси на сервере VMHeaven

Обратному прокси нужно немного: инстанс Nginx или Caddy перед несколькими приложениями спокойно работает на самом младшем тарифе Standard KVM, а сколько ресурсов понадобится больше — решают сами приложения за ним. У каждого сервера свой IPv4-адрес и root-доступ, поэтому порты 80 и 443 — ваши, а постоянная защита от DDoS стоит перед ним на уровне сети. Свежий Ubuntu VPS или Debian VPS — самый короткий путь к такой настройке.

Частые вопросы

Что такое nginx?

Nginx — веб-сервер, который на практике чаще всего работает как обратный прокси: принимает запросы, предназначенные одному или нескольким веб-серверам, решает, какой backend их обработает, передаёт запрос туда и возвращает ответ посетителю. По пути он обычно обрабатывает HTTPS, кеширует, сжимает и балансирует нагрузку между backend-серверами.

Что такое обратный прокси (reverse proxy)?

Сервер, который стоит перед одним или несколькими веб-серверами и получает каждый запрос вместо них — посетитель общается только с прокси, а backend остаётся скрытым. DNS направляет домен на IP прокси, тот открывает своё отдельное соединение к нужному backend-приложению и передаёт туда запрос с заголовками X-Forwarded-For и X-Forwarded-Proto, которые сохраняют настоящего клиента и схему.

Чем обратный прокси отличается от балансировщика нагрузки?

Балансировщик нагрузки — это обратный прокси, у которого основная задача именно распределять запросы между несколькими одинаковыми backend-серверами; любой обратный прокси с более чем одним backend уже балансирует. Отдельные выделенные балансировщики также умеют работать на уровне TCP, вообще не читая HTTP, тогда как Nginx, Caddy и Traefik обычно работают на уровне HTTP.

Читайте также

Все статьи раздела