Copias de seguridad cifradas antes de subirlas a la nube

Una copia de la base de datos guardada en un servicio en la nube es una copia de los datos de tus usuarios en manos de un tercero. Cómo cifrarla con age usando una clave pública y cómo comprobar que de verdad se puede restaurar.

El hub hacía una copia de su base de datos cada noche y la enviaba fuera de casa, a un almacenamiento en la nube. Bien, en apariencia: si la Raspberry Pi ardía, los datos sobrevivían. El problema es que ese archivo contenía, en texto legible, todo lo que los usuarios habían apuntado. Quien tuviera acceso a esa cuenta en la nube, o el propio proveedor, podía leerlo. Esto es lo que cambiamos.

Una copia es otra copia de los datos

Es fácil pensar en las copias de seguridad como algo aparte del sistema. No lo son: son el sistema entero, congelado, en otro sitio. Todo el cuidado que se pone en proteger la base de datos (contraseñas, permisos, cifrado de las conexiones) no sirve de nada si cada noche se deja una copia completa y en claro en un servidor ajeno.

Hay dos soluciones. No sacar las copias de casa, con lo que un incendio o un robo se lo lleva todo. O sacarlas de forma que quien las guarde no pueda leerlas.

Cifrar con clave pública

La forma obvia de cifrar es con una contraseña. Pero entonces la contraseña tiene que estar en el servidor que hace la copia, y si alguien entra en ese servidor se lleva las copias y la forma de abrirlas.

El cifrado de clave pública lo evita. Hay dos claves emparejadas:

  • La pública solo sirve para cifrar. No es secreta: puede estar escrita en la configuración del servidor, a la vista.
  • La privada es la única que descifra. No está en el servidor ni en la nube: la guarda el responsable, fuera de todo el sistema.

El servidor puede crear copias cifradas pero no puede abrir ninguna, ni siquiera las que él mismo hizo. Si alguien compromete el servidor o la cuenta en la nube, obtiene archivos ilegibles.

Usamos age, una herramienta libre pensada justo para esto: cifrar ficheros con una clave pública, sin las decenas de opciones de las herramientas clásicas.

Cómo queda

El par de claves se genera una vez:

age-keygen -o copias.key
# imprime la clave pública, que empieza por «age1…»

Y la copia nocturna pasa de guardar el volcado tal cual a cifrarlo antes de que salga del proceso que lo genera:

pg_dumpall > volcado.sql
gzip -c volcado.sql | age -r "$CLAVE_PUBLICA" > copia.sql.gz.age
rm volcado.sql

Dos detalles que parecen menores y no lo son:

  • Comprobar que ha salido cifrada. Tras generar el archivo, el proceso mira que empiece por la cabecera de age. Si no, falla y no sube nada. Un fallo silencioso en el cifrado volvería a dejar copias en claro sin que nadie se enterase.
  • No encadenarlo todo en una sola línea. Si el volcado falla a mitad, una cadena de órdenes puede dar por buena una copia vacía. Hacer el volcado en un paso aparte permite detectarlo.

Una copia que no se ha restaurado no es una copia

Lo más importante de todo el proceso no es cifrar, es comprobar que se puede descifrar. Lo hicimos de verdad:

  1. Se lanzó una copia a mano.
  2. Se descargó el archivo desde el almacenamiento, no desde el servidor que lo creó.
  3. Se comprobó que empezaba por la cabecera de age, es decir, que lo guardado estaba cifrado.
  4. Se descifró con la clave privada y se verificó que era un volcado completo: todas las bases de datos y todas las tablas.
  5. Se borró la versión descifrada.

Restaurar, llegado el caso, es la operación inversa:

age -d -i copias.key copia.sql.gz.age | gunzip | psql

La clave privada es ahora lo más valioso

Este esquema traslada el riesgo. Antes, el peligro era que alguien leyera las copias. Ahora es perder la clave privada: sin ella, las copias son ruido y no hay recuperación posible.

  • Guárdala en al menos dos sitios que no dependan del servidor: un gestor de contraseñas y, por ejemplo, una copia en papel.
  • No la dejes en la misma máquina que hace las copias. Si está ahí, el cifrado no protege de nada.
  • Apunta junto a ella cómo se restaura. Dentro de dos años no te acordarás.

Conservar lo justo

Las copias antiguas también son datos personales. Si un usuario borra su cuenta, sigue apareciendo en las copias anteriores hasta que estas se eliminen. Por eso conviene una retención corta y explícita. Aquí se guardan siete copias diarias; pasada una semana, la más antigua se borra, también en la nube. Ese plazo es el que figura en la política de privacidad, y el que se le puede dar a quien pregunte cuándo desaparecerán sus datos del todo.

Al activar el cifrado, las copias antiguas sin cifrar no hubo que borrarlas a mano: la propia rotación las fue sustituyendo por cifradas en una semana.

No te olvides de la otra base de datos

Ciframos primero la copia de las apps y dimos el trabajo por hecho. Después caímos en que el servicio de inicio de sesión tiene su propia base de datos, con los emails de todos los usuarios, y su propia copia nocturna, que seguía saliendo en claro. Se cifró con la misma clave. Al auditar copias de seguridad hay que listar todo lo que se copia, no solo lo que uno tiene en mente.

Qué nos llevamos

  • Una copia fuera de casa sin cifrar es una cesión de datos a un tercero.
  • Con clave pública, el servidor cifra pero no puede descifrar.
  • Hay que probar la restauración, de principio a fin, al menos una vez.
  • La clave privada merece tanto cuidado como los propios datos.