Résoudre le problème de Discourse déployé avec 1Panel où toutes les adresses IP des utilisateurs apparaissent comme provenant de Cloudflare au lieu des vraies adresses IP des navigateurs

J’ai installé 1Panel sur un VPS, déployé Discourse (via conteneur) et configuré OpenResty (via conteneur) comme reverse proxy. Le domaine est hébergé chez Cloudflare avec le CDN activé (petit nuage jaune). Voici comment résoudre le problème où l’IP des utilisateurs apparaît comme provenant de Cloudflare au lieu de leur véritable IP.

1. Créer une tâche planifiée dans 1Panel pour télécharger chaque semaine la liste des IPs Cloudflare et la sauvegarder dans le répertoire de configuration d’OpenResty.

  1. Cliquez sur “Tâches planifiées” dans le menu latéral gauche de 1Panel.

  2. Cliquez sur “Créer une tâche planifiée” en haut à droite.

  3. Remplissez les paramètres suivants (vous pouvez copier-coller directement) :

  • Type de tâche : Choisissez Script Shell.

  • Nom de la tâche : Par exemple Mise à jour automatique des plages d'IP Cloudflare.

  • Fréquence d’exécution : Il est recommandé de choisir Hebdomadaire (par exemple, tous les samedis à 03h00).

  • Contenu du script : Copiez et collez le code complet ci-dessous (Attention : modifiez d’abord le nom du conteneur et le chemin du répertoire de configuration au début du script) :

#!/bin/bash
# Zone de configuration
CONTAINER_NAME="Nom du conteneur OpenResty dans 1Panel"
# Modifiez pour le répertoire proxy du site spécifié
CONF_DIR="/opt/1panel/www/sites/www.votre-domaine.club/proxy"

echo "[$(date)] Début du téléchargement des dernières plages d'IP depuis l'official Cloudflare..."
TEMP_DIR=$(mktemp -d)

# Télécharger et convertir la liste des IPs en format reconnaissable par 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

# Vérifier et déplacer les fichiers
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)] Les fichiers de configuration ont été mis à jour avec succès dans $CONF_DIR."
else
    echo "[$(date)] Erreur : Échec du téléchargement des IPs Cloudflare !"
    rm -rf $TEMP_DIR
    exit 1
fi
rm -rf $TEMP_DIR

# Tester et recharger Nginx
echo "[$(date)] Test de la configuration Nginx en cours..."
if docker exec $CONTAINER_NAME nginx -t; then
    docker exec $CONTAINER_NAME nginx -s reload
    echo "[$(date)] Succès ! Rechargement de la configuration OpenResty terminé."
else
    echo "[$(date)] Échec ! Le test de configuration Nginx n'a pas réussi."
    exit 1
fi

Une fois la tâche créée, vous n’avez pas besoin d’attendre samedi pour tester : trouvez la tâche que vous venez de créer dans la liste des “Tâches planifiées”.

Cliquez sur le bouton “Rapport” à droite. Consultez la fenêtre de journal qui s’affiche. Si les dernières lignes affichent Succès ! Rechargement de la configuration OpenResty terminé, cela signifie que tout le processus fonctionne parfaitement à l’intérieur de 1Panel !

2. Configuration supplémentaire de realip pour OpenResty

Créez un nouveau fichier dans le répertoire /opt/1panel/www/sites/www.votre-domaine/proxy/ de la machine hôte (le nom du fichier peut être quelconque, mais doit se terminer par .conf, car il sera automatiquement chargé par include *.conf de la configuration principale) : realip.conf

# Utiliser le chemin à l'intérieur du conteneur
include /www/sites/www.votre-domaine/proxy/cf-ips-v4.conf;
include /www/sites/www.votre-domaine/proxy/cf-ips-v6.conf;

real_ip_header CF-Connecting-IP;
real_ip_recursive on;

3. Recharger OpenResty

docker exec Nom du conteneur OpenResty dans 1Panel nginx -t
docker exec Nom du conteneur OpenResty dans 1Panel nginx -s reload

4. Vérifier si OpenResty a obtenu l’IP réelle

Consultez le journal d’accès (access log) d’OpenResty :

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

Si la configuration est correcte, la première IP dans le journal devrait devenir votre véritable IP publique, et non une plage d’IP Cloudflare comme 173.245.x.x.

5. Côté Discourse

Modifiez app.yml et ajoutez le contenu suivant dans le bloc run: :

  # Après le déploiement de Discourse via Docker, ajoutez les trois sections suivantes pour garantir la transmission de l'IP réelle des utilisateurs du forum
  - 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;

Ainsi, le Nginx intégré à Discourse :

  1. Fera confiance au sous-réseau Docker (172.16.0.0/12)
  2. Lira l’IP réelle depuis x-forwarded-for
  3. Analysera de manière récursive les multiples niveaux de proxy

6. Remarques

L’ajout de - "templates/cloudflare.template.yml" dans app.yml de Discourse n’est efficace que lorsque Discourse est directement exposé à Cloudflare. Comme un reverse proxy OpenResty est ajouté entre les deux, l’IP source visible par le conteneur Discourse est en réalité celle de la passerelle Docker (comme 172.17.0.1 ou 172.18.0.1), donc la directive set_real_ip_from <CloudflareIP> dans ce modèle ne correspondra pas.

Par conséquent, il n’est pas nécessaire d’ajouter - "templates/cloudflare.template.yml" dans app.yml de Discourse.


Mise à jour du 03/07/2026

2 « J'aime »

Référence

Handling the chain of trust of the end user’s real IP - Docs / Self-Hosting - Discourse Meta

Mettre à jour le sujet.