# Reverse proxy в Nginx: proxy_pass и заголовки бэкенда

> Reverse proxy в Nginx: как настроить proxy_pass, передать заголовки клиента бэкенду и не потерять IP посетителя.

## Что такое reverse proxy в Nginx и зачем он нужен

Reverse proxy — сервер, который принимает запросы от клиентов и передаёт их на один или несколько бэкендов: приложение на Node.js, Python, Java или другой инстанс Nginx. Клиент обращается только к прокси и не видит внутреннюю структуру сервиса. Nginx умеет работать как reverse proxy из коробки — для этого достаточно директивы `proxy_pass` внутри блока `location`.

Reverse proxy на Nginx решает несколько задач сразу: терминирует TLS перед приложением, отдаёт статику напрямую в обход медленного бэкенда, скрывает внутренние порты и IP-адреса, добавляет заголовки безопасности. На VDS ZevsHost.net такую схему часто ставят перед Node.js или Python-приложением: Nginx слушает порт 80 и 443, а сам сервис работает на localhost и наружу не смотрит.

- Балансировка нагрузки между несколькими копиями приложения.
- Единый SSL-сертификат на весь набор внутренних сервисов.
- Кэширование ответов бэкенда без изменения кода приложения.

## Настройка proxy\_pass: базовый пример

Минимальный конфиг — блок `server` с одним `location`, который пересылает все запросы на локальное приложение по HTTP.

```
server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}
```

Если `location` задан с завершающим слэшем, а в `proxy_pass` указан путь, Nginx заменяет совпавшую часть URI на этот путь. Без пути в `proxy_pass` исходный URI передаётся бэкенду как есть — это самый предсказуемый вариант, особенно если приложение само разбирает маршруты. Подробнее про правила совпадения путей — в статье про [приоритет location](https://www.zevshost.net/ru/kb/nginx-location-prioritet/).

## Передача заголовков клиента на бэкенд

По умолчанию Nginx заменяет заголовок `Host` на адрес бэкенда и не сообщает приложению реальный IP посетителя. Если это не поправить, в логах приложения будет виден только IP самого Nginx, а ссылки в письмах и редиректах могут указывать на localhost вместо настоящего домена.

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

Приложение на бэкенде должно доверять этим заголовкам только если запрос пришёл именно от локального Nginx, иначе клиент сможет подделать X-Forwarded-For напрямую.

## Таймауты и буферы: за что отвечает каждый параметр

Если бэкенд отвечает медленно или отдаёт большой ответ, стандартные таймауты и буферы Nginx могут оборвать соединение раньше времени. Значения ниже — рабочая точка отсчёта для обычного веб-приложения, не для стриминга.

| Параметр | Назначение | Типичное значение |
| --- | --- | --- |
| proxy\_connect\_timeout | ожидание установки TCP-соединения с бэкендом | 5s |
| proxy\_send\_timeout | время между записями данных на бэкенд | 60s |
| proxy\_read\_timeout | время между чтениями ответа от бэкенда | 60s |
| proxy\_buffer\_size | буфер для первой части ответа (заголовки) | 4k |
| proxy\_buffers | количество и размер буферов для тела ответа | 8 4k |

Слишком короткий `proxy_read_timeout` — частая причина 504 Gateway Timeout на тяжёлых запросах вроде экспорта отчёта или загрузки файла. Слишком маленькие буферы заставляют Nginx писать временные файлы на диск, что заметно на VDS с медленным диском.

## Reverse proxy к нескольким серверам через upstream

Если приложение работает в нескольких копиях, вместо одного адреса в `proxy_pass` используют блок `upstream` с списком серверов.

```
upstream backend {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002 backup;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://backend;
    }
}
```

Nginx по умолчанию распределяет запросы по кругу (round robin) и пропускает сервер, помеченный `backup`, пока остальные живы. Про алгоритмы распределения нагрузки и проверку здоровья бэкендов — в отдельной статье про [балансировщик Nginx](https://www.zevshost.net/ru/kb/nginx-load-balancer/). Если перед reverse proxy нужен ещё и HTTPS, сертификат настраивается на внешнем сервере — см. статью про [SSL/TLS в Nginx](https://www.zevshost.net/ru/kb/nginx-ssl-tls-nastroika/).

## Чек-лист: проверка reverse proxy перед продакшеном

- Заголовки Host, X-Real-IP и X-Forwarded-For переданы бэкенду и видны в его логах.
- Команда `nginx -t` проходит без ошибок после каждой правки конфига.
- Таймауты подобраны под реальное время ответа приложения, а не оставлены по умолчанию.
- При нескольких бэкендах в upstream настроен хотя бы один запасной сервер.
- Ответ проверен командой `curl -I http://app.example.com/` — заголовки и код статуса совпадают с ожидаемыми.

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

### Что будет, если не настроить передачу заголовков X-Real-IP и X-Forwarded-For на бэкенд?

Если заголовки Host, X-Real-IP и X-Forwarded-For не передать, приложение на бэкенде увидит в логах только адрес самого Nginx, а не реальный IP посетителя сайта. Из-за этого ссылки в письмах и редиректах могут указывать на внутренний адрес вместо настоящего домена, а любая логика, завязанная на IP клиента, перестанет работать корректно.

### Можно ли полностью доверять заголовку X-Forwarded-For, который передаёт клиент?

Нет, доверять этому заголовку без ограничений нельзя: если запрос приходит не через локальный Nginx, а напрямую от клиента, он может подставить в X-Forwarded-For произвольное значение. Приложение должно принимать этот заголовок как достоверный только тогда, когда точно уверено, что запрос прошёл через ваш собственный прокси, а не от внешнего источника.

### Почему при обращении через reverse proxy иногда возникает ошибка 504 Gateway Timeout?

Ошибка 504 обычно возникает, когда ответ бэкенда занимает больше времени, чем разрешает proxy\_read\_timeout — например, при экспорте тяжёлого отчёта или долгой загрузке файла. Nginx обрывает соединение раньше, чем приложение успевает ответить. Решение — увеличить именно этот таймаут для медленных запросов, не трогая остальные настройки прокси.

### Подходят ли типичные значения таймаутов и буферов reverse proxy для потокового видео или больших файлов?

Нет, значения из статьи — это рабочая точка отсчёта именно для обычных веб-запросов, а не для стриминга. Потоковая передача видео или крупных файлов требует другого подхода к буферам и таймаутам, иначе соединение будет обрываться или Nginx начнёт писать временные файлы на диск, что особенно заметно на сервере с медленным диском.

---

Источник: https://www.zevshost.net/ru/kb/nginx-reverse-proxy/
