Linux

Nginx proxy_pass: правильное проксирование, URI, заголовки и WebSocket

proxy_pass выглядит просто, но одна из самых частых ошибок Nginx — неверное понимание того, как меняется URI при наличии или отсутствии завершающего слеша.

Простой reverse proxy

location /api/ {
    proxy_pass http://127.0.0.1:8080;
}

В таком варианте исходный URI передаётся backend почти как есть.

proxy_pass с URI

location /api/ {
    proxy_pass http://127.0.0.1:8080/;
}

Здесь часть URI, совпавшая с location, заменяется URI из proxy_pass. Именно из-за этой разницы часто появляются двойные или потерянные префиксы.

Передаём исходный Host и IP

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;

Backend должен доверять этим заголовкам только от вашего reverse proxy, иначе клиент сможет подделать исходный IP.

WebSocket

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

location /socket/ {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_pass http://127.0.0.1:3000;
}

HTTPS до backend

Если upstream использует HTTPS, не отключайте проверку сертификата просто ради устранения ошибки. Настройте доверенный CA и SNI, если backend ожидает имя хоста.

Таймауты

Не увеличивайте proxy_read_timeout до огромных значений как универсальное решение. Сначала выясните, почему backend отвечает долго.

Проверка

nginx -t
systemctl reload nginx
curl -I https://example.com/api/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *