Falha no login com "Unknown error"

Olá,

Estou executando minha própria instância do Discourse, instalada seguindo o guia básico de instalação Docker. O problema que estou enfrentando é que, após alguns dias de uso do fórum, o login para de funcionar completamente. Note que sou o único usuário neste fórum. Mas, infelizmente, não sei o que está causando o erro.

Passos para reproduzir #1:

  1. Instale um novo servidor Discourse seguindo as instruções do guia de instalação Docker.
  2. Após a conclusão do assistente de configuração, verifique se você consegue sair e entrar novamente com sucesso.
  3. Continue usando o fórum normalmente. Apenas crie algumas categorias e posts. Talvez altere o tema padrão.
  4. Após alguns dias ou semanas de uso normal, você não conseguirá fazer login novamente após sair. O login falha com “Erro desconhecido” (exibido no formulário de login).

Passos para reproduzir #2:

  1. Instale um novo servidor Discourse seguindo as instruções do guia de instalação Docker.
  2. Após a conclusão do assistente de configuração, verifique se você consegue sair e entrar novamente com sucesso.
  3. Restaure um backup de outra instância do Discourse onde o login estava falhando.
  4. Enquanto o restaure está em andamento, você recebe uma mensagem pop-up informando que você foi desconectado. O restaure foi bem-sucedido, mas o login falha com “Erro desconhecido” (exibido no formulário de login).

Tentei depurar o problema sozinho, mas não consegui encontrar nenhuma mensagem de erro relevante. Isso é o que tentei até agora:

cd /var/discourse
./launcher enter app
tail -F log/production_errors.log
tail -F log/production.log
tail -F log/unicorn.stderr.log
tail -F log/unicorn.stdout.log

Nenhuma mensagem de erro aparece nesses logs durante uma falha no login. O que mais posso fazer para ajudar a depurar esse problema? Obrigado antecipadamente.

Você olhou em /logs no navegador da web quando logado como administrador?

OK, descobri algo. O login falha assim que ativo a configuração ‘forçar https’. Minha instância do Discourse está atrás de um servidor proxy com terminação SSL. Assim que desativo ‘forçar https’, o login volta a funcionar. Portanto, isso provavelmente não é um bug do Discourse, mas sim um problema na configuração da minha infraestrutura.

Também fiz como você sugeriu, mas não houve nenhuma mensagem de erro nos logs.

Finalmente encontrei a solução. O cabeçalho X-Forwarded-Proto deve ser definido; ele é usado para identificar o protocolo (HTTP ou HTTPS) que o cliente usou para se conectar ao seu proxy ou balanceador de carga.

Como utilizo o HAProxy como servidor proxy, precisei adicionar esta linha à minha configuração do HAProxy:

http-request set-header X-Forwarded-Proto https if { ssl_fc }

Agora o login funciona corretamente, mesmo com a opção “forçar HTTPS” ativada.

Também quero usar o protocolo PROXY em qualquer conexão estabelecida com meu servidor Discourse. O protocolo PROXY informa a outra ponta (ou seja, o servidor Discourse) sobre os endereços da conexão de entrada, para que ele possa saber o endereço do cliente ou o endereço público ao qual ele acessou. Sem essa alteração, o Nginx não saberá o endereço do cliente e todos os logs conterão o endereço do seu servidor de proxy reverso em vez disso. As seguintes alterações resolvem o problema:

root@talk3:/var/discourse# git diff
diff --git a/templates/web.template.yml b/templates/web.template.yml
index a60e6ef..55cb5f2 100644
--- a/templates/web.template.yml
+++ b/templates/web.template.yml
@@ -116,6 +116,19 @@ run:
       to: daemon off;

   - replace:
+      filename: /etc/nginx/nginx.conf
+      from: /# server_tokens off;/
+      to: |
+        server_tokens off;
+        real_ip_header proxy_protocol;
+        set_real_ip_from 192.168.1.19;  # endereço do servidor proxy
+
+  - replace:
+      filename: "/etc/nginx/conf.d/discourse.conf"
+      from: /listen 80;$/
+      to: "listen 80 proxy_protocol;"
+
+  - replace:
       filename: "/etc/nginx/conf.d/discourse.conf"
       from: /upstream[^\}]+\}/m
       to: "upstream discourse {

E instrua o HAProxy a forçar o uso do protocolo PROXY neste servidor:

-    server server-1 192.168.1.27:80 check
+    server server-1 192.168.1.27:80 check send-proxy

Finalmente, execute ./launcher rebuild app e verifique se agora ele registra os endereços dos clientes:

tail -F /var/discourse/shared/standalone/log/var-log/nginx/access.log