Preservando sessões de usuário durante a migração entre hosts

Olá!

Estou me preparando para migrar algumas instâncias do Discourse para uma nova hospedagem. O plano é definir o site antigo como somente leitura, fazer um backup, mover esse backup para a nova hospedagem e restaurá-lo enquanto atualizo as configurações de DNS (com um TTL curto). Todo esse processo foi baseado em guias disponíveis aqui e em outros lugares.

Tenho feito alguns testes preliminares usando uma manipulação no arquivo /etc/hosts para simular a atualização do DNS (e com o DNS sobre HTTPS desativado no navegador também). Até agora, tudo bem.

No entanto, apesar de ter o cuidado de fechar o navegador no site ‘original’ e só abri-lo novamente após a migração completa no site ‘destino’, ele esquece que eu estava logado.

Obviamente, não quero que todos os membros do site sejam desconectados durante a migração. Onde devo procurar ou o que estou esquecendo?

O usuário que estou testando atualmente tem privilégios de administrador e usa autenticação de dois fatores (2FA), e os containers do Discourse estão atrás de um Nginx que encerra o SSL, caso isso faça diferença para o problema.

Agradeço antecipadamente por qualquer orientação!

2 curtidas

Eu também tive esse problema e estou ansioso para resolvê-lo.

Qualquer orientação é bem-vinda.

2 curtidas

Acho que vou tentar criar algumas contas de teste sem 2FA, caso isso tenha algo a ver com o problema. Poucos membros do site usam 2FA, então talvez seja aceitável se forem apenas essas sessões que estão sendo perdidas.

Também vou verificar se os servidores de origem e destino estão sincronizados com o NTP, embora eu ache que eles não podem estar com mais do que alguns segundos de diferença agora.

Além disso, acho que sempre resta analisar o código-fonte para tentar entender o que compõe o token de autenticação e o que pode estar causando o problema… :grimacing:

2 curtidas

O ideal é informar seus usuários sobre a alteração, explicando que eles serão desconectados e precisarão fazer login novamente.

Cada servidor possui sua assinatura única com o SSL configurado.

Será menos trabalhoso pedir que o usuário faça login novamente do que tentar alterar as configurações do servidor.

Basta se desculpar pelo inconveniente causado, mas destaque que a medida é para o bem.

2 curtidas

Mas é realmente esse o caso?

Como os cookies de sessão são afetados pelas “assinaturas” do SSL (especialmente quando, no meu caso, os servidores novo e antigo estão usando os mesmos arquivos de certificado SSL, no mesmo nome de domínio)?

3 curtidas

Embora eu não tenha problema em pedir desculpas aos membros (:slightly_smiling_face:), realmente quero evitar esse cenário, pois consigo visualizar alguns efeitos colaterais indesejados:

  1. Os membros não fazem login novamente e têm menos probabilidade de participar do fórum no futuro.
  2. Os membros esquecem suas senhas e precisam de ajuda para recuperá-las.
  3. Os membros esquecem suas senhas e criam novas contas, deixando muitas “contas zumbi” no fórum e identidades duplicadas perdidas/confusas sem Notas de Usuário ou histórico de posts, etc…

A parte do SSL funciona perfeitamente na frente do Discourse (mesmo com a correção no arquivo hosts), o que, se você pensar bem, deve ser o caso, caso contrário os balanceadores de carga teriam problemas. Até onde sei, o Discourse nem sequer sabe sobre o SSL, pois ele é encerrado no Nginx nesta configuração.

Acho que uma pergunta diferente seria: “é possível migrar um servidor Discourse para um novo IP sem desconectar todos?” Eu assumia que seria, mas talvez essa suposição estivesse errada… :frowning:

3 curtidas

Sei que já tive sessões de fórum que sobreviveram a um backup e restauração. Realmente não tenho certeza do que está acontecendo aqui :frowning:

3 curtidas

Os cookies de sessão são criptografados usando uma chave secreta gerada aleatoriamente, que, por padrão, é armazenada no Redis. Os dados do Redis não são incluídos em um backup, portanto, uma nova chave secreta é gerada quando você restaura o site em um novo servidor.

Você pode definir manualmente a chave secreta usando uma variável de ambiente DISCOURSE_SECRET_KEY_BASE no seu arquivo app.yml. Então, você pode tentar algo como isso para preservar as sessões:

  1. No seu servidor existente, entre no console e encontre a chave secreta no Redis

    pry(main)> GlobalSetting.safe_secret_key_base
    => "5fb9dc98be368599e0a..."
    
  2. Adicione DISCOURSE_SECRET_KEY_BASE à seção env: do seu app.yml no servidor antigo, usando o valor que você encontrou em (1), e reconstrua o app. Em teoria, se tudo der certo, o Discourse agora deve usar o valor do app.yml, e as sessões dos usuários serão mantidas. Você pode verificar se a variável de ambiente está sendo usada executando

    GlobalSetting.secret_key_base
    
  3. Certifique-se de que o app.yml no novo servidor tenha o mesmo SECRET_KEY_BASE. Quando você restaurar o backup, as sessões dos usuários devem ser mantidas

Eu não testei esse fluxo, então, se você planeja usá-lo em um fórum de produção, certifique-se de testá-lo primeiro!

Nota lateral: você absolutamente não deve compartilhar a chave secreta entre múltiplas instâncias do Discourse. A posse da chave secreta permitiria que alguém descriptografasse e modificasse seu cookie de sessão em um site, o que poderia ter consequências de segurança muito graves.

7 curtidas

Excelente — isso é algo que vou testar em uma instância sandbox. Vou ver se consigo relatar se funciona ou não :slight_smile:

Entendido. Agora estou refletindo sobre se deveria haver uma solicitação de recurso para uma opção de exportar essa chave nos backups? Para mim, perder todas as sessões de um site pareceria algo “muito ruim” de acontecer, já que há alguns milhares de contas no site. Praticar a migração revelou esse problema, mas imagino que, se a máquina ou a instância Docker fosse perdida por algum motivo, a chave também seria perdida e enfrentaríamos a mesma perda de sessões.

Seria bom incluir alguma menção a esse “recurso” no tópico sobre migração: Move your Discourse Instance to a Different Server

1 curtida

É um equilíbrio delicado entre segurança e conveniência.

No momento, se alguém conseguir roubar um backup do Discourse, terá todos os dados do fórum. Mas não terá a capacidade de fazer login no fórum ao vivo. As senhas são hash, as chaves de API são hash e os cookies de sessão são criptografados.

Se incluíssemos o segredo dentro do backup, qualquer pessoa que tivesse posse de um backup poderia acessar o fórum ao vivo e realizar phishing/fraude/etc.

Ótimo! Estou totalmente aberto a ter um tópico aqui no Meta explicando como migrar de uma chave secreta do Redis para uma chave secreta do app.yml. Poderia ser vinculado a partir do tópico ‘migrar para um servidor diferente’.

4 curtidas

Na minha humilde opinião, a segurança dos backups padrão também deveria ser aprimorada. Embora senhas e sessões possam ser hashadas e protegidas, pode haver muitos outros dados em mensagens privadas e afins que ainda deveriam permanecer confidenciais. Note especialmente que, em nosso fórum da comunidade, incentivamos as pessoas a usar mensagens privadas para trocar detalhes de contato e organizar vendas ou coletas, em vez de colocar números de telefone e endereços em locais públicos.

A abordagem que estou adotando para backups é acessar a instância, gerar um backup e, em seguida, criptografá-lo imediatamente com uma chave pública usando o GPG. Isso torna o backup inútil para qualquer pessoa que não tenha a chave privada correspondente, que eu armazeno fora do servidor e protejo com uma frase-senha.

Dito isso, se a chave secreta para sessões não mudar, ela só precisa ser feita um backup uma vez, então um procedimento simples para isso é tudo o que é necessário — e espero que seja o que você descreveu acima.

Vou tentar e ver se consigo criar esse tópico para você :slight_smile:

2 curtidas

Muito útil, @david, obrigado!

2 curtidas

O Discourse não oferece mensagens privadas; o recurso se chama Mensagens Pessoais. A distinção é muito importante, pois não há nenhuma sugestão de privacidade.

Os administradores já podem ler todas as MP do site, a menos que a criptografia esteja em uso.

1 curtida

Bom ponto. Mas isso não muda o fato de que os membros podem usar mensagens privadas (MPs) para trocar dados pessoais ou informações que não desejam que sejam de domínio público. Portanto, proteger esses dados na medida do razoável é importante.

Sim, também precisamos confiar nos administradores de cada site que utilizamos, mesmo em sites como o ProtonMail.

1 curtida

Um pouco fora do tópico… mas você pode se interessar por Discourse Encrypt (deprecated) para mensagens verdadeiramente ‘privadas’. Backups vazados ou roubados de MPs criptografadas não seriam legíveis por um atacante.

(embora, como você disse, ainda haja a premissa de que os administradores são confiáveis)

3 curtidas

@david - por favor, você pode verificar a postagem abaixo e dividi-la e movê-la para howto se estiver tudo certo? (Não consigo criar um tópico lá, aliás, o Akismet acabou de ocultar a postagem, então isso também precisa ser corrigido :blush: )

1 curtida

2 posts foram movidos para um novo tópico: Preservando sessões de usuário ao migrar para um novo host

@david - muito, muito obrigado por resolver isso e pelo conselho. Espero que isso ajude outros também — é certamente um alívio para nós poder migrar e manter as sessões :partying_face:

3 curtidas

Este tópico foi fechado automaticamente após 7 horas. Novas respostas não são mais permitidas.