Solución al problema de que Discourse desplegado con 1Panel muestra todas las IPs de usuarios como procedentes de Cloudflare en lugar de la IP real del navegador

He instalado 1Panel en mi VPS, instalé Discourse (despliegue en contenedor) y configuré OpenResty (despliegue en contenedor) como proxy inverso. El dominio está alojado en Cloudflare con el CDN activado (nube amarilla). A continuación, se explica cómo resolver el problema de que la IP de los usuarios aparezca como proveniente de Cloudflare en lugar de la IP real del navegador del usuario.

1. Crear una tarea programada en 1Panel para descargar semanalmente la lista más reciente de IPs de Cloudflare y guardarla en el directorio de configuración de OpenResty.

  1. Haz clic en “Tareas programadas” en el menú lateral izquierdo de 1Panel.

  2. Haz clic en “Crear tarea programada” en la esquina superior derecha.

  3. Completa los siguientes parámetros (puedes copiar y pegar directamente):

  • Tipo de tarea: Selecciona Script Shell.

  • Nombre de la tarea: Por ejemplo, Actualizar automáticamente los rangos de IP de Cloudflare.

  • Ciclo de ejecución: Se recomienda seleccionar Semanal (por ejemplo, cada sábado a las 03:00 a. m.).

  • Contenido del script: Copia y pega el siguiente código completo (Nota: modifica primero el nombre del contenedor y la ruta del directorio de configuración en la parte superior del código):

#!/bin/bash
# Área de configuración
CONTAINER_NAME="Nombre del contenedor de openresty en 1Panel"
# Modifica al directorio proxy del sitio web especificado
CONF_DIR="/opt/1panel/www/sites/www.tudominio.club/proxy"

echo "[$(date)] Iniciando la descarga de los rangos de IP más recientes desde Cloudflare..."
TEMP_DIR=$(mktemp -d)

# Descargar y convertir la lista de IPs al formato reconocido por Nginx
curl -fsS https://www.cloudflare.com/ips-v4 | sed 's/.*/set_real_ip_from \&;/' > $TEMP_DIR/cf-ips-v4.conf
curl -fsS https://www.cloudflare.com/ips-v6 | sed 's/.*/set_real_ip_from \&;/' > $TEMP_DIR/cf-ips-v6.conf

# Verificar y mover los archivos
if [[ -s $TEMP_DIR/cf-ips-v4.conf ]] && [[ -s $TEMP_DIR/cf-ips-v6.conf ]]; then
    mv $TEMP_DIR/cf-ips-v4.conf $CONF_DIR/
    mv $TEMP_DIR/cf-ips-v6.conf $CONF_DIR/
    echo "[$(date)] Los archivos de configuración se han actualizado correctamente en $CONF_DIR."
else
    echo "[$(date)] Error: ¡Fallo al descargar las IPs de Cloudflare!"
    rm -rf $TEMP_DIR
    exit 1
fi
rm -rf $TEMP_DIR

# Probar y recargar Nginx
echo "[$(date)] Realizando prueba de configuración de Nginx..."
if docker exec $CONTAINER_NAME nginx -t; then
    docker exec $CONTAINER_NAME nginx -s reload
    echo "[$(date)] ¡Éxito! Configuración de OpenResty recargada correctamente."
else
    echo "[$(date)] ¡Fallo! La prueba de configuración de Nginx no superó la validación."
    exit 1
fi

Una vez creada la tarea, no es necesario esperar al sábado; puedes probarla inmediatamente: busca la tarea recién creada en la lista de “Tareas programadas”.

Haz clic en el botón “Informe” a la derecha. Revisa la ventana de registros emergente. Si las últimas líneas muestran ¡Éxito! Configuración de OpenResty recargada correctamente, significa que todo el flujo se ha ejecutado perfectamente dentro de 1Panel.

2. Configuración adicional de realip en OpenResty

Crea un nuevo archivo en el directorio del host /opt/1panel/www/sites/www.tudominio/proxy/ (el nombre del archivo puede ser cualquiera, siempre que termine en .conf, ya que será cargado automáticamente por la configuración principal mediante include *.conf): realip.conf

# Usa la ruta dentro del contenedor
include /www/sites/www.tudominio/proxy/cf-ips-v4.conf;
include /www/sites/www.tudominio/proxy/cf-ips-v6.conf;

real_ip_header CF-Connecting-IP;
real_ip_recursive on;

3. Recargar OpenResty

docker exec Nombre del contenedor de openresty en 1Panel nginx -t
docker exec Nombre del contenedor de openresty en 1Panel nginx -s reload

4. Verificar si OpenResty ha obtenido la IP real

Revisa el registro de acceso (access log) de OpenResty:

tail -f /opt/1panel/www/sites/www.tudominio/log/access.log

Si la configuración es correcta, la primera IP en los registros debería convertirse en tu IP pública real, en lugar de rangos de Cloudflare como 173.245.x.x.

5. Lado de Discourse

Edita app.yml y agrega el siguiente contenido dentro del bloque run::

  # Después de desplegar Discourse en Docker, se deben agregar los siguientes tres bloques para asegurar que se transmita la IP real del usuario del foro
  - file:
      path: /etc/nginx/conf.d/outlets/server/set-real-ip-from-docker.conf
      chmod: 644
      contents: |
        set_real_ip_from 172.16.0.0/12;
        set_real_ip_from 127.0.0.1;
  
  - file:
      path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
      chmod: 644
      contents: |
        real_ip_header x-forwarded-for;
  
  - file:
      path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
      chmod: 644
      contents: |
        real_ip_recursive on;

De esta manera, el Nginx integrado en Discourse:

  1. Confía en la red de Docker (172.16.0.0/12)
  2. Lee la IP real desde x-forwarded-for
  3. Analiza recursivamente múltiples capas de proxy

6. Notas adicionales

Agregar - "templates/cloudflare.template.yml" en app.yml de Discourse solo es efectivo cuando Discourse se enfrenta directamente a Cloudflare. Dado que se ha añadido un proxy inverso OpenResty en el medio, la IP de origen que ve el contenedor de Discourse es en realidad la puerta de enlace de Docker (como 172.17.0.1 o 172.18.0.1), por lo que set_real_ip_from <CloudflareIP> en esa plantilla no coincidirá.

Por lo tanto, no es necesario agregar - "templates/cloudflare.template.yml" en app.yml de Discourse.


Actualización del 03-07-2026

2 Me gusta

Referencia

Cadena de confianza para gestionar la IP real del usuario final - Documentación / Autoalojamiento - Discourse Meta

Actualiza la publicación principal del tema.