# 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/uk/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/uk/kb/nginx-load-balancer/). Якщо перед reverse proxy потрібен ще й HTTPS, сертифікат налаштовується на зовнішньому сервері — див. статтю про [SSL/TLS у Nginx](https://www.zevshost.net/uk/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/uk/kb/nginx-reverse-proxy/
