Введение
Discourse должен знать реальный IP-адрес конечного пользователя.
Однако конечный пользователь никогда не подключается к Discourse напрямую, поскольку всегда присутствует один или несколько вышестоящих веб-серверов (nginx, работающий в контейнере Discourse). Таким образом, нам необходим способ надежной передачи этой информации в Discourse.
Решением является заголовок x-forwarded-for. В этой теме я опишу конкретные механизмы корректной обработки этой информации и то, как мы ожидаем её распространения.
Шаблоны
Различные шаблоны для доверия вышестоящим прокси-серверам (например, cloudflare.template.yml или fastly.template.yml) были обновлены, чтобы использовать предсказуемые имена файлов в outlet-ах, вместо того чтобы полагаться на подстановку текста (которая является ненадежной).
Имена файлов
server/real-ip-header.conf
Этот файл содержит заголовок, который nginx, работающий в контейнере, будет использовать как источник истины, например:
real_ip_header x-forwarded-for;
или как указано в шаблоне Cloudflare:
real_ip_header cf-connecting-ip;
server/real-ip-recursive.conf
Если этот файл существует, он управляет рекурсией при обработке заголовка «реального IP». Вам нужно включить это, если перед контейнером Discourse стоит более одного прокси-сервера.
real_ip_recursive on;
Пример:
Cloudflare → Балансировщик нагрузки → Контейнер Discourse (который включает nginx и сам Discourse)
При такой настройке nginx получит x-forwarded-for, который будет выглядеть так:
x-forwarded-for: real_end_user_ip, cloudflare_ip
при подключении с IP-адреса балансировщика нагрузки.
Для обработки этого, сначала nginx определяет, является ли адрес источника подключения (IP-адрес балансировщика нагрузки) доверенным (см. set_real_ip_from), и если да, обрабатывает последний IP-адрес в заголовке x-forwarded-for.
Поскольку этот IP-адрес — cloudflare_ip, nginx должен сделать это снова, проверяя, является ли cloudflare_ip доверенным, и используя следующий IP-адрес, который является real_end_user_ip.
server/set-real-ip-from-ENVIRONMENT.conf
Этот файл содержит директивы, указывающие nginx, каким IP-адресам доверять, и мы можем иметь столько файлов и директив, сколько необходимо.
Шаблоны в discourse_docker создают эти файлы по мере необходимости (например, set-real-ip-from-cloudflare.conf), и если у вас есть дополнительные потребности, вы можете добавить свои собственные.
Пример:
Если вы работаете в AWS и у вас есть ALB перед контейнером Discourse, вы можете добавить дополнительный файл, добавив следующее в определение вашего контейнера (адаптированное под вашу среду):
run:
- file:
path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-aws.conf
chmod: 644
# AWS VPC — 10.42.0.0/16, доверяем любым подключениям из сетей ALB
contents: |
set_real_ip_from 10.42.66.0/24;
set_real_ip_from 10.42.67.0/24;
- file:
path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
chmod: 644
contents: |
real_ip_header x-forwarded-for;