Antecedentes
Discourse debe conocer la dirección IP real del usuario final.
Sin embargo, un usuario final nunca se conecta directamente a Discourse, ya que siempre hay uno o más servidores web upstream (nginx ejecutándose en el contenedor de Discourse) de por medio. Por lo tanto, necesitamos una forma de transmitir esa información a Discourse de manera confiable.
La solución es el encabezado x-forwarded-for. En este tema describiré los mecanismos específicos para manejar adecuadamente esa información y cómo esperamos que se propague.
Plantillas
Las diversas plantillas para confiar en proxies upstream (por ejemplo, cloudflare.template.yml o fastly.template.yml) se han actualizado para usar nombres de archivo predecibles en outlets, en lugar de depender de la sustitución de texto (que es frágil).
Nombres de archivo
server/real-ip-header.conf
Este archivo contiene el encabezado que nginx, ejecutándose en el contenedor, usará como fuente de verdad, por ejemplo:
real_ip_header x-forwarded-for;
o como se establece en la plantilla de Cloudflare:
real_ip_header cf-connecting-ip;
server/real-ip-recursive.conf
Si este archivo existe, controla la recursividad al procesar el encabezado «real IP». Deberás habilitarlo si hay más de un proxy delante del contenedor de Discourse.
real_ip_recursive on;
Ejemplo:
Cloudflare → Balanceador de carga → Contenedor de Discourse (que es nginx + Discourse en sí)
Con esta configuración, nginx recibirá un x-forwarded-for que se verá así:
x-forwarded-for: real_end_user_ip, cloudflare_ip
en una conexión desde una IP de balanceador de carga.
Para procesar esto, primero nginx determina si la dirección de origen de la conexión (la IP del balanceador de carga) es confiable (ver set_real_ip_from) y, de ser así, procesará la última IP del encabezado x-forwarded-for.
Dado que esa dirección IP es cloudflare_ip, nginx luego debe hacer esto otra vez, verificando si cloudflare_ip es confiable y usando la siguiente dirección IP, que es real_end_user_ip.
server/set-real-ip-from-ENVIRONMENT.conf
Este archivo contiene directivas que le dicen a nginx qué direcciones IP confiar, y podemos tener tantos archivos y directivas como sea necesario.
Las plantillas en discourse_docker crean estos archivos según sea necesario (por ejemplo, set-real-ip-from-cloudflare.conf) y si tienes necesidades adicionales, puedes agregar los tuyos propios.
Ejemplo:
Si estás ejecutando en AWS y tienes un ALB delante del contenedor de Discourse, puedes agregar un archivo adicional añadiendo lo siguiente a tu definición de contenedor (adaptado a tu entorno):
run:
- file:
path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-aws.conf
chmod: 644
# La VPC de AWS es 10.42.0.0/16, confía en cualquier conexión de las redes del 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;