Résoudre le problème où tous les adresses IP des utilisateurs s'affichent comme provenant de Cloudflare au lieu de l'IP réelle du navigateur pour Discourse déployé avec 1Panel

J’ai installé 1Panel sur mon VPS, déployé Discourse (via conteneur) et configuré un proxy inverse avec OpenResty (également en conteneur). Mon domaine est hébergé chez Cloudflare, avec le CDN activé (petit nuage jaune). Voici un tutoriel que j’ai rédigé pour résoudre le problème où l’adresse IP des utilisateurs s’affiche comme provenant de Cloudflare au lieu de l’adresse IP réelle de leur navigateur.

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

  1. Dans le menu latéral gauche de 1Panel, cliquez sur “Tâches planifiées”.

  2. Cliquez sur le bouton “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 IP de Cloudflare.

  • Périodicité : Il est recommandé de choisir Hebdomadaire (par exemple, le samedi à 03:00 du matin).

  • Contenu du script : Copiez-collez le code complet ci-dessous (Remarque : modifiez d’abord le nom du conteneur et le chemin du répertoire de configuration situés tout en haut du code) :

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

echo "[$(date)] Début de la récupération des dernières plages IP auprès de Cloudflare..."
TEMP_DIR=$(mktemp -d)

# Récupérer et convertir la liste des IP au format lisible 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)] Fichiers de configuration mis à jour avec succès dans $CONF_DIR."
else
    echo "[$(date)] Erreur : Échec de la récupération des IP de 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 la 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. Examinez la fenêtre de journal qui s’ouvre. Si les dernières lignes affichent Succès ! Rechargement de la configuration OpenResty terminé, cela signifie que tout le processus fonctionne parfaitement au sein de 1Panel !

II. Configuration complémentaire realip pour OpenResty

Dans le répertoire de l’hôte /opt/1panel/www/sites/www.votredomaine/proxy/, créez un nouveau fichier (le nom est arbitraire, il doit simplement se terminer par .conf pour être automatiquement chargé par l’instruction include *.conf de la configuration principale) : realip.conf

real_ip_header CF-Connecting-IP;
real_ip_recursive on;

III. Recharger OpenResty

docker exec NomDuConteneurOpenRestyDans1Panel nginx -t
docker exec NomDuConteneurOpenRestyDans1Panel nginx -s reload

IV. Vérifier si OpenResty a récupéré l’adresse IP réelle

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

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

Si la configuration est correcte, la première adresse IP dans le journal devrait correspondre à votre véritable adresse IP publique, et non à un segment Cloudflare comme 173.245.x.x.

V. Remarques concernant Discourse

L’ajout de - "templates/cloudflare.template.yml" dans le fichier app.yml de Discourse n’est efficace que lorsque Discourse est directement exposé à Cloudflare. Comme nous avons ajouté un proxy inverse OpenResty intermédiaire, le conteneur Discourse voit l’adresse IP source comme étant celle de la passerelle Docker (par exemple 172.17.0.1 ou 172.18.0.1). Par conséquent, la directive set_real_ip_from <CloudflareIP> présente dans ce modèle ne correspondra pas.

Cependant, tant que vous avez restauré l’adresse IP réelle au niveau d’OpenResty en suivant les étapes ci-dessus et que vous transmettez un en-tête X-Forwarded-For propre, le backend Rails de Discourse pourra correctement identifier l’adresse IP réelle de l’utilisateur, car Rails fait déjà confiance par défaut aux segments de réseau privés Docker comme 172.x.x.x.

Ainsi, il n’est pas nécessaire d’ajouter - "templates/cloudflare.template.yml" dans le fichier app.yml de Discourse.