Registro inconsistente ou ausente e último IP

Temos uma instalação do Discourse, mantida há vários anos, mas atualmente na versão mais recente (2.4.0beta2) usando a imagem Docker mais recente, em um endereço IP público, sem proxy ou outras camadas na frente, com certificados LetsEncrypt.

Às vezes, o IP de registro do usuário e o último IP funcionam perfeitamente; outras vezes, não. Não vejo padrão algum. Por exemplo, aqui está um usuário criado há 7h, com endereços sem sentido:

Outro usuário criado há 17h está perfeitamente correto:

E assim segue: em alguns usuários está tudo certo, em outros não. Alguma ideia do que está acontecendo?

Uma coisa que me chama a atenção agora, ao analisar, é que pode ser que esses usuários estejam acessando via IPv6, já que nunca vi um endereço IPv6 nesses campos. O Discourse não entende IPv6? O proxy do Docker não entende ou não passa as informações relevantes? Ou é algo mais?

O Discourse definitivamente entende, mas você precisará configurar seu servidor e tudo o que estiver na frente dele para que o IPv6 funcione, etc.

O IPv6 está funcionando muito bem, e estamos usando as imagens Docker recomendadas configuradas com os modelos web + data. Não há nada mais na frente. O que devemos ajustar?

Vale lembrar que nosso arquivo container.yml existe há alguns anos, embora inclua os modelos mais recentes e as próprias imagens sejam reconstruídas com frequência. Será que algo mudou ao longo do tempo?

Parece que outras pessoas executando a configuração padrão do Docker estão com o mesmo problema.

https://meta.discourse.org/t/why-are-my-301-redirects-not-working-ipv6-users-also-show-as-localhost/80442/9

É difícil dizer. Acabei de auditar os últimos ~8 novos usuários que se registraram em talk.commonmark.org, que é uma instalação padrão muito comum, e todos eles tinham endereços IPv4 válidos para o Último IP e o IP de Registro (às vezes os dois diferiam, também).

Sei que, se as contas de usuário forem criadas por meio de SSO ou outras vias incomuns, isso pode afetar os IPs relatados ali. Todos esses usuários aos quais você se refere são registros normais feitos por meio do diálogo padrão de novo usuário no Discourse?

Algum desses endereços era IPv6?

Não, nenhum deles estava, mas não sei se esse host de colocation até oferece IPv6.

Então, tenho certeza de que não apresentará o problema de mostrar localhost em vez de endereços IPv6 para usuários que acessam via IPv6. Isso não significa que o problema não exista.

O problema não existe na hospedagem oficial do Discourse, pelo menos, e ela é compatível com IPv6. Também não vejo problemas em uma instalação padrão em um host de colocation aleatório. Não sei o mais o que dizer, além de que você não respondeu à minha pergunta bastante importante.

Ah, sim, essas são inscrições normais, sem SSO ou contas associadas.

Não duvido que funcione na sua hospedagem, mas você não usa a configuração “padrão” do Docker que a maioria dos usuários usa, certo? Quero dizer, tenho certeza de que é possível que funcione, dado um proxy configurando os cabeçalhos corretos, etc. A questão é apenas se a configuração padrão está fazendo isso e, se não estiver, se podemos fazê-la fazer isso.

Tenho quase certeza de que você precisa adicionar um trecho ao seu app.yml que instrua o nginx a reconhecer seu endereço IPv6 e repassar o endereço do cliente. Ainda não consegui descobrir como fazer isso, no entanto. Os tópicos sobre execução de um proxy reverso têm exemplos de IPv6, que oferecem dicas.

Isso está na minha lista de coisas para resolver, mas tenho uma lista bastante longa. Acabei desativando o IPv6, acho que por causa desse problema, mas talvez devido a alguma outra falta de conhecimento sobre IPv6.

(Jeff, você pode obter um bloco de IPv6 roteado, mas precisa solicitá-lo e depois configurar seus hosts para usá-lo.)

O Meta é apenas uma instalação padrão do Docker com um proxy reverso externo e suporta IPv6 de forma excelente:

Existe uma seção no seu discourse.conf que instrui o set_real_ip com seu endereço IPv6, algo assim?

    - replace:
        filename: /etc/nginx/conf.d/discourse.conf
        from: "types {"
        to: |
          set_real_ip_from 192.168.1.0/24;
          set_real_ip_from 172.18.0.0/24;
          set_real_ip_from 172.17.0.0/24;
          set_real_ip_from <ALGUM_COISA_DE_ENDEREÇO_IP_V6_AQUI?>
          real_ip_recursive on;
          real_ip_header X-Forwarded-For;
          types {

Acho que o proxy reverso externo é a chave — não creio que isso seja solucionável de forma alguma, ou pelo menos não facilmente, apenas dentro do contêiner Docker.

Resolvi o problema fazendo o Docker do Discourse ouvir em um socket Unix e colocando um Caddy na mesma máquina (fora do Docker). A configuração do Caddy é trivial, inclui o Let’s Encrypt e agora funciona conforme o esperado também para IPv6.

forum.example.com {
  proxy / unix:/var/discourse/shared/web-only/nginx.http.sock {
    transparent
    websocket
  }
}