Preservación de sesiones de usuario al migrar entre hosts

¡Hola!

Me estoy preparando para migrar algunas instancias de Discourse a un nuevo alojamiento. El plan consiste en dejar el sitio antiguo en modo solo lectura, realizar una copia de seguridad, trasladarla al nuevo alojamiento y restaurarla mientras se actualizan los ajustes de DNS (con un TTL corto). Todo este proceso se basa en guías disponibles aquí y en otros lugares.

He estado realizando algunas pruebas preliminares usando un truco en el archivo /etc/hosts para simular la actualización de DNS (y también desactivando DNS sobre HTTPS en el navegador). Hasta ahora, todo va bien.

Sin embargo, a pesar de tener el cuidado de cerrar el navegador en el sitio ‘origen’ y solo abrirlo después de completar la migración en el sitio ‘destino’, el navegador olvida que estaba conectado.

Obviamente, no quiero que todos los miembros del sitio se desconecten durante la migración. ¿Dónde debería buscar o qué estoy pasando por alto?

El usuario que estoy probando actualmente tiene privilegios de administrador y utiliza autenticación de dos factores (2FA), y los contenedores de Discourse están detrás de Nginx, que finaliza la conexión SSL, por si eso influye en el problema.

¡Gracias de antemano por cualquier orientación!

2 Me gusta

Yo también he tenido este problema y estoy muy interesado en resolverlo.

Cualquier indicación será apreciada.

2 Me gusta

Creo que voy a intentar crear algunas cuentas de prueba sin 2FA, por si eso tiene algo que ver. Muy pocos miembros del sitio usan 2FA, así que podría ser aceptable si solo se pierden esas sesiones.

También verificaré que los servidores de origen y destino estén sincronizados con NTP, aunque ahora creo que no pueden estar más que unos pocos segundos desfasados entre sí.

Aparte de eso, supongo que siempre queda el código fuente para intentar averiguar qué se incluye en el token de autenticación y qué podría estar causando el problema… :grimacing:

2 Me gusta

Lo mejor sería informar a tus usuarios sobre el cambio, indicando que serán desconectados y deberán iniciar sesión nuevamente.

Cada servidor tiene su firma única con SSL activado.

Será menos complicado hacer que el usuario inicie sesión de nuevo que intentar cambiar la configuración del servidor.

Solo pide disculpas por las molestias causadas, pero aclara que es para mejorar.

2 Me gusta

¿Es realmente así?

¿Cómo afectan las firmas de SSL a las cookies de sesión (especialmente en mi caso, donde el nuevo y el antiguo servidor utilizan los mismos archivos de certificado SSL en el mismo nombre de dominio)?

3 Me gusta

Aunque no tengo problema en disculparme con los miembros (:slightly_smiling_face:), realmente quiero evitar ese escenario, ya que puedo ver algunos efectos secundarios desfavorables:

  1. Los miembros no vuelven a iniciar sesión y es menos probable que participen en el foro en el futuro.
  2. Los miembros olvidan su contraseña y necesitan ayuda para recuperarla.
  3. Los miembros olvidan sus contraseñas y crean nuevas cuentas, dejando muchas “cuentas zombis” en el foro e identidades duplicadas perdidas o confusas sin notas de usuario o historial de publicaciones, etc.

El tema del SSL funciona perfectamente frente a Discourse (incluso con el truco del archivo de hosts), lo cual, si lo piensas, debe ser así; de lo contrario, los equilibradores de carga tendrían problemas. Por lo que sé, Discourse ni siquiera sabe que existe el SSL, ya que en esta configuración se termina en Nginx.

Supongo que otra pregunta sería: “¿Es posible migrar un servidor de Discourse a una nueva IP sin desconectar a todos?”. Había asumido que sí, pero tal vez esa suposición era incorrecta… :frowning:

3 Me gusta

Sé que definitivamente he tenido sesiones de foro que sobrevivieron a una copia de seguridad y restauración. Realmente no estoy seguro de qué está pasando aquí :frowning:

3 Me gusta

Las cookies de sesión se cifran utilizando una clave secreta generada aleatoriamente que, de forma predeterminada, se almacena en Redis. Los datos de Redis no se incluyen en las copias de seguridad, por lo que se genera una nueva clave secreta al restaurar el sitio en un servidor nuevo.

Puedes establecer manualmente la clave secreta utilizando la variable de entorno DISCOURSE_SECRET_KEY_BASE en tu archivo app.yml. Así que podrías probar algo como esto para preservar las sesiones:

  1. En tu servidor existente, entra en la consola y encuentra la clave secreta en Redis:

    pry(main)> GlobalSetting.safe_secret_key_base
    => "5fb9dc98be368599e0a..."
    
  2. Añade DISCOURSE_SECRET_KEY_BASE a la sección env: de tu archivo app.yml en el servidor antiguo, utilizando el valor que encontraste en el paso (1), y vuelve a compilar la aplicación. En teoría, si todo sale bien, Discourse ahora debería usar el valor del archivo app.yml y las sesiones de usuario persistirán. Puedes verificar que se está utilizando la variable de entorno ejecutando:

    GlobalSetting.secret_key_base
    
  3. Asegúrate de que el archivo app.yml en el nuevo servidor tenga la misma SECRET_KEY_BASE. Cuando restaures la copia de seguridad, las sesiones de usuario deberían persistir.

No he probado este flujo, así que si planeas usarlo en un foro de producción, asegúrate de probarlo primero.

Nota al margen: absolutamente no debes compartir la clave secreta entre múltiples instancias de Discourse. El conocimiento de la clave secreta permitiría a alguien descifrar y modificar su cookie de sesión en un sitio, lo que podría tener consecuencias de seguridad muy graves.

7 Me gusta

Excelente, esto es algo que probaré en una instancia de entorno de pruebas. Veré si puedo informar si funciona o no :slight_smile:

Entendido. Ahora estoy pensando si debería haber una solicitud de función para incluir una opción de exportación de esta clave en las copias de seguridad. Para mí, perder todas las sesiones en un sitio parecería algo “muy grave”, ya que hay varios miles de cuentas en el sitio. Practicar la migración ha puesto de manifiesto este problema, pero supongo que si la máquina o la instancia de Docker se perdieran por alguna razón, la clave también se perdería y nos enfrentaríamos a la misma pérdida de sesiones.

También sería bueno incluir alguna nota sobre esta “función” en el tema de migración: Move your Discourse Instance to a Different Server

1 me gusta

Es un delicado equilibrio entre seguridad y comodidad.

En este momento, si alguien logra robar una copia de seguridad de Discourse, tiene todos los datos del foro. Pero no tiene la capacidad de iniciar sesión en el foro en vivo. Las contraseñas están hasheadas, las claves de API están hasheadas y las cookies de sesión están cifradas.

Si incluyéramos el secreto dentro de la copia de seguridad, cualquier persona en posesión de una copia de seguridad podría obtener acceso al foro en vivo y llevar a cabo suplantación de identidad, fraude, etc.

¡Suena genial! Estoy totalmente abierto a tener un tema aquí en Meta explicando cómo migrar de una clave secreta de Redis a una clave secreta de app.yml. Podría enlazarse desde el tema “moverse a un servidor diferente”.

4 Me gusta

En mi humilde opinión, también debería mejorarse la seguridad de las copias de seguridad predeterminadas. Aunque las contraseñas y las sesiones puedan estar cifradas y protegidas, podría haber muchos otros datos en mensajes privados y similares que deberían seguir siendo confidenciales. Cabe destacar especialmente que en nuestro foro comunitario animamos a las personas a utilizar mensajes privados para intercambiar datos de contacto y organizar ventas o entregas, en lugar de publicar números de teléfono y direcciones en lugares públicos.

El enfoque que estoy adoptando para las copias de seguridad es acceder a la instancia, generar una copia de seguridad y luego cifrarla inmediatamente con una clave pública utilizando GPG. Esto hace que la copia de seguridad sea inútil para cualquiera que no tenga la clave privada correspondiente, la cual almaceno fuera del servidor y protejo con una frase de contraseña.

Dicho esto, si la clave secreta para las sesiones no cambia, solo necesita ser respaldada una vez, por lo que todo lo que se necesita es un procedimiento sencillo para ello, y espero que sea lo que has descrito anteriormente.

Lo intentaré y veré si puedo crear ese tema para ti :slight_smile:

2 Me gusta

¡Muy útil, @david, gracias!

2 Me gusta

Discourse no ofrece mensajes privados; la función se llama Mensajes Personales. La distinción es muy importante, ya que no hay ninguna sugerencia de privacidad.

Los administradores ya pueden leer cada MP en el sitio a menos que se utilice cifrado.

1 me gusta

Buen punto. Pero eso no cambia el hecho de que los miembros pueden usar los mensajes privados para intercambiar datos personales o cosas que no desean que sean de dominio público. Por lo tanto, proteger estos datos en la medida de lo razonable es importante.

Sí, también tenemos que confiar en los administradores de cada sitio que usamos, incluso en sitios como ProtonMail.

1 me gusta

Un poco fuera de tema… pero quizás te interese Discourse Encrypt (deprecated) para mensajes verdaderamente ‘privados’. Las copias de seguridad filtradas o robadas de mensajes privados cifrados no serían legibles para un atacante.

(aunque, como mencionaste, todavía se asume que los administradores son de confianza)

3 Me gusta

@david - ¿podrías revisar el siguiente mensaje y, si está bien, dividirlo y moverlo a howto? (No puedo crear un tema allí, y además Akismet acaba de ocultar el mensaje, así que eso también hay que arreglarlo :blush: )

1 me gusta

2 publicaciones se separaron en un nuevo tema: Mantener las sesiones de usuario al migrar a un nuevo host

@david - muchísimas gracias por solucionarlo y por el consejo. Espero que también ayude a otros. ¡Sin duda es un alivio para nosotros poder migrar y mantener las sesiones :partying_face:

3 Me gusta

Este tema se cerró automáticamente después de 7 horas. Ya no se permiten nuevas respuestas.