Gestionar la "cadena de confianza" de la IP real del usuario final

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;
4 Me gusta