1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6

# конспект · шаг 6 из 6

Конспект: заголовки к бэкенду и realip

выжимка - её можно унести в заметки

Что бэкенд знает о клиенте - и почему по умолчанию почти ничего.

Что видит бэкенд без настройки

Что Значение по умолчанию Почему
Host app:8000 nginx подставляет $proxy_host из proxy_pass
IP клиента адрес nginx соединение открыл он
схема http между nginx и бэкендом TLS обычно нет

Четыре строки, которые пишут почти всегда

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;
клиент 203.0.113.9 → CDN 10.0.0.5 → nginx
пришло:  X-Forwarded-For: 203.0.113.9
уйдёт:   X-Forwarded-For: 203.0.113.9, 10.0.0.5

Без X-Forwarded-Proto приложение строит ссылки на http:// и получает бесконечный редирект за TLS-терминатором.

realip: сделать адрес настоящим

set_real_ip_from 10.0.0.5;        # адрес самого прокси, а не его подсеть
real_ip_header X-Forwarded-For;

После этого $remote_addr сам становится адресом клиента - и его же видят логи, limit_req и allow/deny. Настоящий адрес соединения остаётся в $realip_remote_addr, и в лог пишут оба.

X-Forwarded-For recursive off (умолчание) recursive on
203.0.113.9, 172.24.0.99 172.24.0.99 203.0.113.9
8.8.8.8, 9.9.9.9, 172.24.0.99 172.24.0.99 9.9.9.9

off берёт последний адрес цепочки - тот, что вписал твой прокси, подделать его нельзя. on идёт влево мимо доверенных и нужен, только когда доверенных звеньев несколько и их число меняется.

CORS

Разрешение даёт Access-Control-Allow-Origin, источник в нём ровно один, флаг always обязателен. Непростые запросы предваряются OPTIONS, которому нужен ответ 204 со списком методов, заголовков и Max-Age. Несколько источников разруливают картой с белым списком; звёздочка запрещает куки.

Ловушки джокера

  • X-Forwarded-For - не доверенные данные. Клиент может прислать любой адрес, и он доедет до бэкенда даже без единой строки настройки. Доверенным его делает только set_real_ip_from.
  • real_ip_recursive on с широким списком доверия - дыра. Замер на цепочке из двух nginx: при списке 172.24.0.0/16 подделанный 8.8.8.8 попадает в логи, при списке из одного адреса прокси - нет.
  • Заголовки исчезают уровнем ниже. proxy_set_header наследуется всё или ничего: одна своя строка в location отменяет весь набор. Симптом - Host молча вернулся к app:8000. Лечится отдельным файлом и include.
  • Host пустым значением не убрать - он вернётся к адресу из proxy_pass. Остальные заголовки пустое значение убирает.
  • Место директив realip - http или server. В location подмена срабатывает не для всех фаз.
  • Без always CORS-заголовок пропадает на 4xx и 5xx, и ошибка приложения приходит во фронтенд как «CORS policy».

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.