Discourse mostra IP do servidor/localhost como IP do usuário

Olá, implantei o Discourse no meu próprio servidor, tudo funciona normalmente, exceto a detecção do endereço IP do usuário. Eu até criei um script PHP (fora do contêiner Docker) para obter todos os cabeçalhos onde o IP pode estar:

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

Detalhes:
O servidor tem o painel BrainyCP instalado com Apache e Nginx (atualmente o site usa Nginx, que faz proxy reverso para o contêiner Docker)
HTTP_CF_CONNECTING_IP retorna 127.0.0.1 dentro do contêiner Docker, mas fora eles têm valores normais
Sem alterar o cabeçalho usando comandos personalizados, o Discourse exibe o IP do servidor.

(Em breve adicionarei mais detalhes, pois minha instância do Discourse está sendo reconstruída)

Não tenho muita certeza sobre a sua configuração, mas notei o Cloudflare na sua postagem. Você adicionou o template do CloudFlare ao seu arquivo app.yml?

  - "templates/cloudflare.template.yml"

EDIT: usei as aspas erradas " "

Não, eu adicionei à lista de modelos, agora aguardando a reconstrução

1 curtida

Reconstruído, mas ainda mostra o IP do servidor (comentei os comandos personalizados

## Quaisquer comandos personalizados para executar após a compilação
run:
  - exec: echo "Início dos comandos personalizados"
  ## Se você quiser definir o endereço de e-mail 'De' para seu primeiro registro, descomente e altere:
  ## Após receber o primeiro e-mail de inscrição, comente a linha novamente. Só precisa ser executado uma vez.
  - 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 "Fim dos comandos personalizados"

Preciso descomentá-los? (também quero notar que eles não funcionaram nem antes de eu adicionar o template do cloudflare ao app.yml))

Descomentado, $sent_http_cf_connection_ip retorna 127.0.0.1
image

O Nginx provavelmente está relatando 127.0.0.1 e não o próprio Discourse, você provavelmente precisará configurar o realip no nginx.

Já adicionei cloudflare.template.yml, que adiciona diretivas realip, mas ainda não está funcionando.
Eu até removi comandos personalizados que estavam mudando para um cabeçalho personalizado e agora o Discourse relata o IP do servidor para todos os usuários em vez de localhost.

Além disso, esta é a configuração do Nginx para o domínio zeronet.space gerada pelo próprio painel

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 é implantado nas portas 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;
}

Também quero observar o “caminho” da solicitação:
Usuário -> Cloudflare -> Servidor (Nginx -> Docker -> Discourse)
E note que o IP do usuário é visível fora do docker no cabeçalho CF-Connecting-IP do Cloudflare

Não sei muito sobre como funciona o sistema de IP real do Cloudflare, mas suspeito que o seu Discourse nginx precisará de set_real_ip_from para ser o endereço IP que ele vê como seu proxy nginx. 127.0.0.1? Algum outro endereço interno? O endereço público? Não tenho certeza de qual ele veria.

Assim que você souber qual é esse endereço, acho que o que eu faria seria deixar o template do cloudflare lá, então adicionar um novo replace apenas para set_real_ip_from.

Além disso, seu proxy nginx precisará ser configurado para repassar o cabeçalho CF-Connecting-IP se ele ainda não estiver configurado para fazer isso ou se não o fizer por padrão. Não posso realmente ajudar com essa parte.

Mesmo caminho que eu, meu problema era que o nginx não estava configurado para aceitar o IP do docker como um intervalo para definir o 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;

Então eu vou Usuário > Cloudflare > Servidor 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"
## Descomente estas duas linhas se desejar adicionar Lets Encrypt (https)
#  - "templates/web.ssl.template.yml"
#  - "templates/web.letsencrypt.ssl.template.yml"
#  - "templates/web.socketed.template.yml"
  - "templates/cloudflare.template.yml"
4 curtidas

Esta pode ser a causa dos seus problemas. Tente configurar o Discourse em um servidor sem nenhum painel ou proxy reverso instalado e relate se você experimentar o mesmo problema.

Como um primeiro passo, comece alterando o bloco de localização para o Discourse para corresponder aos detalhes fornecidos aqui: Run other websites on the same machine as Discourse

1 curtida

Isso não é uma solução de problema, basicamente comprar um novo servidor dedicado de 30€/mês pode resolver qualquer coisa lol (este tópico não existirá então).

Tentarei postar os resultados aqui

Preciso adicionar cabeçalhos também na configuração do Nginx do Discourse? (dentro do docker) Porque ele ainda está mostrando o endereço do servidor em vez dos usuários.

Com base no seu caminho, isso não faz sentido para mim.

Seu nginx vai para o discourse para o docker, por que o seu discourse usaria seu próprio nginx também?

Não sei, adicionei suas diretivas Nginx às minhas através do painel (também verifiquei via ssh), mas ainda mostra o IP do servidor.

Este é o meu app.yml:

## este é o modelo de contêiner Docker Discourse tudo-em-um e autônomo
##
## Após fazer alterações neste arquivo, você DEVE reconstruir
## /var/discourse/launcher rebuild app
##
## TENHA MUITO CUIDADO AO EDITAR!
## ARQUIVOS YAML SÃO SUPER SUPER SENSÍVEIS A ERROS DE ESPAÇAMENTO OU ALINHAMENTO!
## visite http://www.yamllint.com/ para validar este arquivo conforme necessário

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/cloudflare.template.yml"
## Descomente estas duas linhas se desejar adicionar o Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## quais portas TCP/IP este contêiner deve expor?
## Se você quiser que o Discourse compartilhe uma porta com outro servidor web como Apache ou nginx,
## veja https://meta.discourse.org/t/17247 para detalhes
expose:
  - "31080:80"   # http
  - "31443:443" # https

params:
  db_default_text_search_config: "pg_catalog.russian"

  ## Defina db_shared_buffers para um máximo de 25% da memória total.
  ## será definido automaticamente pelo bootstrap com base na RAM detectada, ou você pode substituir
  db_shared_buffers: "4096MB"

  ## pode melhorar o desempenho da classificação, mas adiciona uso de memória por conexão
  #db_work_mem: "40MB"

  ## Qual revisão Git este contêiner deve usar? (padrão: 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

  ## Quantas requisições web concorrentes são suportadas? Depende da memória e núcleos da CPU.
  ## será definido automaticamente pelo bootstrap com base nas CPUs detectadas, ou você pode substituir
  UNICORN_WORKERS: 8

  ## TODO: O nome de domínio que esta instância do Discourse responderá
  ## Obrigatório. O Discourse não funcionará com um número IP simples.
  DISCOURSE_HOSTNAME: 'zeronet.space'

  ## Descomente se você quiser que o contêiner seja iniciado com o mesmo
  ## nome de host (-h option) especificado acima (padrão "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Lista de e-mails separados por vírgula que se tornarão administradores e desenvolvedores
  ## na inscrição inicial, exemplo 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'contact@zeronet.space'

  ## TODO: O servidor de e-mail SMTP usado para validar novas contas e enviar notificações
  # ENDEREÇO SMTP, nome de usuário e senha são necessários
  # AVISO, o caractere '#' na senha SMTP pode causar problemas!
  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"

  ## Se você adicionou o modelo Lets Encrypt, descomente abaixo para obter um certificado SSL gratuito
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## O endereço CDN http ou https para esta instância do Discourse (configurado para puxar)
  ## veja https://meta.discourse.org/t/14857 para detalhes
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## A chave de licença do MaxMind para pesquisa de endereço IP
  ## veja https://meta.discourse.org/t/-/137387/23 para detalhes
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## O contêiner Docker é sem estado; todos os dados são armazenados em /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins vão aqui
## veja https://meta.discourse.org/t/19157 para detalhes
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Quaisquer comandos personalizados para executar após a construção
run:
  - exec: echo "Início dos comandos personalizados"
  ## Se você quiser definir o endereço de e-mail 'De' para o seu primeiro registro, descomente e altere:
  ## Após receber o primeiro e-mail de inscrição, comente a linha novamente. Ela só precisa ser executada uma vez.
  - exec: rails r "SiteSetting.notification_email='noreply@zeronet.space'"
  - exec: echo "Fim dos comandos personalizados"

A resposta foi vinculada acima. Você precisa de algo assim.

4 curtidas

Isso corrigiu problemas com a detecção de IP (agora tudo funciona normalmente), mas agora algumas imagens não estão carregando

EDIT: isso foi um problema de cache, agora tudo funciona! Obrigado a todos!

2 curtidas

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