Discourse affiche l'IP du serveur/localhost comme IP de l'utilisateur

Bonjour, j’ai déployé Discourse sur mon propre serveur, tout fonctionne normalement sauf la détection de l’adresse IP de l’utilisateur. J’ai même créé un script PHP (en dehors du conteneur Docker) pour obtenir tous les en-têtes où l’IP peut se trouver :

REMOTE_ADDR: 212.58.xxx.xxx
SERVER_PORT: 80
SERVER_ADDR: 85.25.xxx.xxx
SERVER_SOFTWARE: Apache:
HTTP_CF_CONNECTING_IP: 212.58.xxx.xxx
HTTP_CDN_LOOP: cloudflare
HTTP_X_REAL_IP: 162.158.xxx.xxx

Détails :
Le serveur a le panneau BrainyCP installé avec Apache et Nginx (actuellement le site Web utilise Nginx, qui agit comme un proxy inverse pour le conteneur Docker).
HTTP_CF_CONNECTING_IP renvoie 127.0.0.1 à l’intérieur du conteneur Docker, mais à l’extérieur, ils ont des valeurs normales.
Sans modifier l’en-tête à l’aide de commandes personnalisées, Discourse affiche l’adresse IP du serveur.

(Bientôt, j’ajouterai plus de détails car mon instance Discourse est en cours de reconstruction)

Je ne suis pas vraiment sûr de votre configuration, mais j’ai remarqué Cloudflare dans votre publication. Avez-vous ajouté le modèle CloudFlare à votre fichier app.yml ?

  - "templates/cloudflare.template.yml"

EDIT : utilisé le mauvais " "

Non, je l’ai ajouté à la liste des modèles, j’attends maintenant la reconstruction.

1 « J'aime »

Reconstruit, mais il affiche toujours l’IP du serveur (j’ai commenté les commandes personnalisées

## Toute commande personnalisée à exécuter après la construction
run:
  - exec: echo "Début des commandes personnalisées"
  ## Si vous souhaitez définir l'adresse e-mail 'De' pour votre première inscription, décommentez et modifiez :
  ## Après avoir reçu le premier e-mail d'inscription, re-commentez la ligne. Elle ne doit s'exécuter qu'une seule fois.
  - exec: rails r "SiteSetting.notification_email='noreply@zeronet.space'"
  #- replace:
  #   filename: /etc/nginx/conf.d/discourse.conf
  #   from: "types {"
  #   to: |
  #     set_real_ip_from 85.25.134.45;
  #     real_ip_header CF-Connection-IP;
  #     real_ip_recursive on;
  #     types {
  #- replace:
  #   filename: /etc/nginx/conf.d/discourse.conf
  #   from: $proxy_add_x_forwarded_for
  #   to: $send_http_cf_connection_ip;
  #   global: true
  - exec: echo "Fin des commandes personnalisées"

Dois-je les décommenter ? (je tiens également à signaler qu’elles n’ont pas fonctionné, même avant que j’aie ajouté le modèle cloudflare à app.yml))

Non commenté, $sent_http_cf_connection_ip donne 127.0.0.1
image

Nginx signale probablement 127.0.0.1 et non Discourse lui-même, vous devrez probablement configurer realip dans nginx

J’ai déjà ajouté cloudflare.template.yml qui ajoute des directives realip, mais cela ne fonctionne toujours pas.
J’ai même supprimé les commandes personnalisées qui modifiaient l’en-tête personnalisé et maintenant Discourse signale l’adresse IP du serveur pour tous les utilisateurs au lieu de localhost.

Voici également la configuration Nginx pour le domaine zeronet.space générée par le panneau lui-même

server {
	listen 85.25.xxx.xx:443 ssl http2;
	server_name  zeronet.space www.zeronet.space;
	root  /home/ay0ks/workspace/sites/zeronet.space;
	
	# ssl on;
	ssl_certificate  /etc/certs/ay0ks/zeronet.space_1655753906.crt;
	ssl_certificate_key /etc/certs/ay0ks/zeronet.space_1655753906.key;
	#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	#ssl_ciphers  "HIGH:!RC4:!aNULL:!MD5:!kEDH";
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
	ssl_ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:ECDHE:!COMPLEMENTOFDEFAULT;
	ssl_prefer_server_ciphers on;
	
	add_header Strict-Transport-Security 'max-age=604800';
	
	access_log /etc/nginx/vhost_logs/zeronet.space_access;
	error_log /etc/nginx/vhost_logs/zeronet.space_error;
	
	location ~ /.well-known {
		allow all;
	}
	
	location ~ /\\.ht {
		deny all;
		access_log off;
		log_not_found off;
	}

	location / {
		root /home/ay0ks/workspace/sites/zeronet.space;
		proxy_pass http://85.25.xxx.xx:31080; # Discourse est déployé sur les ports 31080/31443
		proxy_redirect     off;
		proxy_force_ranges on;
		proxy_set_header   Host $host;
		proxy_set_header   X-Real-IP $remote_addr;
		proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header   X-Forwarded-Proto $scheme;
		proxy_set_header   HTTPS $scheme;
		
		proxy_cache off;
		proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
		#access_log /etc/nginx/vhost_logs//home/ay0ks/workspace/sites/zeronet.space;
		
		proxy_cache_valid 3s;
		proxy_cache_min_uses 2;
		# proxy_cache_lock on;
		# proxy_cache_use_stale error timeout;
		# proxy_cache_use_stale updating http_502 http_504;
		limit_conn lone 100;
		# limit_req zone=ltwo burst=10;
		
		client_body_buffer_size    128k;
		client_max_body_size       1024m;
		proxy_connect_timeout      180;
		proxy_send_timeout         180;
		proxy_read_timeout         180;
		send_timeout               180;
		
		proxy_buffer_size          4k;
		proxy_buffers              8 32k;
		proxy_busy_buffers_size    68k;
		proxy_temp_file_write_size 10m;
	}

	# error_page  404              /404.html;
	# error_page   500 502 503 504  /50x.html;
}

Je tiens également à noter le « chemin » de la requête :
Utilisateur -> Cloudflare -> Serveur (Nginx -> Docker -> Discourse)
Et notez que l’IP de l’utilisateur est visible à l’extérieur de docker dans l’en-tête CF-Connecting-IP de Cloudflare.

Je ne connais pas grand-chose au fonctionnement de la gestion de la vraie adresse IP par Cloudflare, mais je soupçonne que votre Nginx Discourse aura besoin de set_real_ip_from configuré avec l’adresse IP que votre Nginx proxy voit. 127.0.0.1 ? Une autre adresse interne ? L’adresse publique ? Je ne suis pas sûr de ce qu’il verrait.

Une fois que vous saurez de quelle adresse il s’agit, je pense que ce que je ferais, c’est de laisser le modèle Cloudflare en place, puis d’ajouter un nouveau replace juste pour set_real_ip_from.

En plus de cela, votre Nginx proxy devra être configuré pour transmettre l’en-tête CF-Connecting-IP s’il n’est pas déjà configuré pour le faire ou s’il ne le fait pas déjà par défaut. Je ne peux pas vraiment vous aider sur ce point.

Même chemin que moi, mon problème était que nginx n’était pas configuré pour prendre l’IP docker comme une plage pour définir le realip.

set_real_ip_from 172.18.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
set_real_ip_from 172.18.0.0/16;

Donc, je vais de Utilisateur > Cloudflare > Serveur Nginx (SWAG Docker) > Discourse

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $remote_addr;
templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Décommentez ces deux lignes si vous souhaitez ajouter Lets Encrypt (https)
#  - "templates/web.ssl.template.yml"
#  - "templates/web.letsencrypt.ssl.template.yml"
#  - "templates/web.socketed.template.yml"
  - "templates/cloudflare.template.yml"
4 « J'aime »

Cela pourrait être la cause de vos problèmes. Essayez d’installer Discourse sur un serveur sans aucun panneau ni proxy inverse installé et signalez si vous rencontrez le même problème.

Dans un premier temps, commencez par modifier le bloc d’emplacement pour Discourse afin qu’il corresponde aux détails fournis ici : Run other websites on the same machine as Discourse

1 « J'aime »

Ce n’est pas une solution à un problème, fondamentalement acheter un nouveau serveur dédié à 30€/mois peut tout résoudre lol (ce fil de discussion n’existera alors plus).

J’essaierai et publierai les résultats ici

Dois-je également ajouter des en-têtes dans la configuration Nginx de Discourse ? (à l’intérieur de Docker) Parce qu’il m’affiche toujours l’adresse du serveur au lieu de celle des utilisateurs.

D’après votre chemin, cela n’a aucun sens pour moi.

Votre nginx va à discourse vers docker, pourquoi votre discourse utiliserait-il son propre nginx également ?

Je ne sais pas, j’ai ajouté vos directives Nginx aux miennes via le panneau (j’ai également vérifié depuis ssh), mais il affiche toujours l’adresse IP du serveur.

Voici mon fichier app.yml :

## voici le modèle de conteneur Docker Discourse tout-en-un et autonome
##
## Après avoir apporté des modifications à ce fichier, vous DEVEZ reconstruire
## /var/discourse/launcher rebuild app
##
## SOYEZ TRÈS PRUDENT LORS DE L'ÉDITION !
## LES FICHIERS YAML SONT EXTRÊMEMENT SENSIBLES AUX ERREURS D'ESPACEMENT OU D'ALIGNEMENT !
## visitez http://www.yamllint.com/ pour valider ce fichier si nécessaire

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/cloudflare.template.yml"
## Décommentez ces deux lignes si vous souhaitez ajouter Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## quels ports TCP/IP ce conteneur doit-il exposer ?
## Si vous souhaitez que Discourse partage un port avec un autre serveur web comme Apache ou nginx,
## voir https://meta.discourse.org/t/17247 pour plus de détails
expose:
  - "31080:80"   # http
  - "31443:443" # https

params:
  db_default_text_search_config: "pg_catalog.russian"

  ## Définissez db_shared_buffers à un maximum de 25 % de la mémoire totale.
  ## sera défini automatiquement par bootstrap en fonction de la RAM détectée, ou vous pouvez le remplacer
  db_shared_buffers: "4096MB"

  ## peut améliorer les performances de tri, mais ajoute de l'utilisation de mémoire par connexion
  #db_work_mem: "40MB"

  ## Quelle révision Git ce conteneur doit-il utiliser ? (défaut : tests-passed)
  #version: tests-passed

env:
  LC_ALL: ru_RU.UTF-8
  LANG: ru_RU.UTF-8
  LANGUAGE: ru_RU.UTF-8
  DISCOURSE_DEFAULT_LOCALE: ru

  ## Combien de requêtes web simultanées sont prises en charge ? Dépend de la mémoire et des cœurs CPU.
  ## sera défini automatiquement par bootstrap en fonction des CPU détectés, ou vous pouvez le remplacer
  UNICORN_WORKERS: 8

  ## TODO : Le nom de domaine auquel cette instance Discourse répondra
  ## Requis. Discourse ne fonctionnera pas avec un simple numéro IP.
  DISCOURSE_HOSTNAME: 'zeronet.space'

  ## Décommentez si vous souhaitez que le conteneur soit démarré avec le même
  ## nom d'hôte (-h option) que celui spécifié ci-dessus (par défaut "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO : Liste des e-mails délimités par des virgules qui seront rendus administrateurs et développeurs
  ## lors de la première inscription, exemple 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'contact@zeronet.space'

  ## TODO : Le serveur de messagerie SMTP utilisé pour valider les nouveaux comptes et envoyer des notifications
  # L'adresse SMTP, le nom d'utilisateur et le mot de passe sont requis
  # ATTENTION, le caractère '#' dans le mot de passe SMTP peut causer des problèmes !
  DISCOURSE_SMTP_ADDRESS: smtp.zeronet.space
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: noreply@zeronet.space
  DISCOURSE_SMTP_PASSWORD: "xxxxxxx"
  DISCOURSE_SMTP_ENABLE_START_TLS: true
  DISCOURSE_SMTP_AUTHENTICATION: login
  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
  DISCOURSE_NOTIFICATION_EMAIL: "noreply@zeronet.space"
  #DISCOURSE_SMTP_DOMAIN: "zeronet.space"

  ## Si vous avez ajouté le modèle Lets Encrypt, décommentez ci-dessous pour obtenir un certificat SSL gratuit
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## L'adresse CDN http ou https pour cette instance Discourse (configurée pour tirer)
  ## voir https://meta.discourse.org/t/14857 pour plus de détails
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## La clé d'adresse IP de géolocalisation Maxmind pour la recherche d'adresses IP
  ## voir https://meta.discourse.org/t/-/137387/23 pour plus de détails
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## Le conteneur Docker est sans état ; toutes les données sont stockées dans /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Les plugins vont ici
## voir https://meta.discourse.org/t/19157 pour plus de détails
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Toutes les commandes personnalisées à exécuter après la construction
run:
  - exec: echo "Début des commandes personnalisées"
  ## Si vous souhaitez définir l'adresse e-mail 'De' pour votre première inscription, décommentez et modifiez :
  ## Après avoir reçu le premier e-mail d'inscription, re-commentez la ligne. Elle ne doit s'exécuter qu'une seule fois.
  - exec: rails r "SiteSetting.notification_email='noreply@zeronet.space'"
  - exec: echo "Fin des commandes personnalisées"

La réponse était liée ci-dessus. Vous avez besoin de quelque chose comme ceci.

4 « J'aime »

Cela a corrigé les problèmes de détection d’IP (maintenant tout fonctionne normalement) mais certaines images ne se chargent pas maintenant

EDIT : c’était un problème de cache, maintenant tout fonctionne ! Merci à tous !

2 « J'aime »

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.