sql >> Base de Datos >  >> RDS >> MariaDB

Cómo cifrar sus copias de seguridad de MySQL y MariaDB

Por lo general, nos ocupamos de las cosas que valoramos, ya sea un teléfono inteligente costoso o los servidores de la empresa. Los datos son uno de los activos más importantes de la organización, y aunque no los vemos, hay que protegerlos con mucho cuidado. Implementamos el cifrado de datos en reposo para cifrar archivos de bases de datos o volúmenes completos que contienen nuestros datos. Implementamos el cifrado de datos en tránsito mediante SSL para asegurarnos de que nadie pueda husmear y recopilar datos enviados a través de redes. Las copias de seguridad no son diferentes. No importa si se trata de una copia de seguridad completa o incremental, almacenará al menos una parte de sus datos. Como tal, las copias de seguridad también deben cifrarse. En esta publicación de blog, analizaremos algunas opciones que puede tener cuando se trata de encriptar copias de seguridad. Sin embargo, primero veamos cómo puede cifrar sus copias de seguridad y cuáles podrían ser casos de uso para esos métodos.

¿Cómo cifrar su copia de seguridad?

Cifrar archivo local

En primer lugar, puede cifrar fácilmente los archivos existentes. Imaginemos que tiene un proceso de respaldo que almacena todos sus respaldos en un servidor de respaldo. En algún momento, decidió que era hora de implementar el almacenamiento de copias de seguridad fuera del sitio para la recuperación ante desastres. Puede usar S3 o una infraestructura similar de otros proveedores de nube para eso. Por supuesto, no desea cargar copias de seguridad sin cifrar en ningún lugar fuera de su red de confianza, por lo tanto, es fundamental que implemente el cifrado de copias de seguridad de una forma u otra. Un método muy simple, que no requiere ningún cambio en sus scripts de copia de seguridad existentes, sería crear un script que tome un archivo de copia de seguridad, lo cifre y lo cargue en S3. Uno de los métodos que puede usar para cifrar los datos es usar openssl:

openssl enc -aes-256-cbc -salt -in backup_file.tar.gz -out backup_file.tar.gz.enc -k yoursecretpassword

Esto creará un nuevo archivo encriptado, 'backup_file.tar.gz.enc' en el directorio actual. Siempre puedes descifrarlo más tarde ejecutando:

openssl aes-256-cbc -d -in backup_file.tar.gz.enc -out backup_file.tar.gz -k yoursecretpassword

Este método es muy simple, pero tiene algunos inconvenientes. El más grande son los requisitos de espacio en disco. Al cifrar como describimos anteriormente, debe mantener tanto el archivo sin cifrar como el cifrado y, como resultado, necesita un espacio en disco del doble del tamaño del archivo de copia de seguridad. Por supuesto, dependiendo de sus requisitos, esto podría ser algo que desee:mantener los archivos no cifrados localmente mejorará la velocidad de recuperación; después de todo, descifrar los datos también llevará algún tiempo.

Cifrar copia de seguridad sobre la marcha

Para evitar la necesidad de almacenar datos cifrados y no cifrados, es posible que desee implementar el cifrado en la etapa anterior del proceso de copia de seguridad. Podemos hacerlo a través de tuberías. Los pipes son, en definitiva, una forma de enviar los datos de un comando a otro. Esto hace posible crear una cadena de comandos que procesa datos. Puede generar los datos, luego comprimirlos y cifrarlos. Un ejemplo de tal cadena podría ser:

mysqldump --all-databases --single-transaction --triggers --routines | gzip | openssl  enc -aes-256-cbc -k mypass > backup.xb.enc

También puede usar este método con xtrabackup o mariabackup. De hecho, este es el ejemplo de la documentación de MariaDB:

mariabackup --user=root --backup --stream=xbstream  | openssl  enc -aes-256-cbc -k mypass > backup.xb.enc

Si lo desea, puede incluso intentar cargar datos como parte del proceso:

mysqldump --all-databases --single-transaction --triggers --routines | gzip | openssl  enc -aes-256-cbc -k mysecretpassword | tee -a mysqldump.gz.enc | nc 10.0.0.102 9991

Como resultado, verá un archivo local 'mysqldump.gz.enc' y una copia de los datos se canalizará a un programa que hará algo al respecto. Usamos 'nc', que transmitió datos a otro host en el que se ejecutó lo siguiente:

nc -l 9991 > backup.gz.enc

En este ejemplo, usamos mysqldump y nc, pero puede usar xtrabackup o mariabackup y alguna herramienta que cargará la transmisión en Amazon S3, Google Cloud Storage o algún otro proveedor de nube. Se puede usar cualquier programa o script que acepte datos en stdin en lugar de 'nc'.

Usar encriptación incrustada

En algunos de los casos, una herramienta de copia de seguridad tiene soporte integrado para el cifrado. Un ejemplo aquí es xtrabackup, que puede cifrar internamente el archivo. Desafortunadamente, mariabackup, aunque es una bifurcación de xtrabackup, no es compatible con esta función.

Antes de que podamos usarlo, debemos crear una clave que se usará para cifrar los datos. Se puede hacer ejecutando el siguiente comando:

[email protected]:~# openssl rand -base64 24
HnliYiaRo7NUvc1dbtBMvt4rt1Fhunjb

Xtrabackup puede aceptar la clave en formato de texto sin formato (usando la opción --encrypt-key) o puede leerla desde un archivo (usando la opción --encrypt-key-file). Este último es más seguro ya que pasar contraseñas y claves como texto sin formato a los comandos da como resultado almacenarlos en el historial de bash. También puede verlo claramente en la lista de procesos en ejecución, lo cual es bastante malo:

root      1130  0.0  0.6  65508  4988 ?        Ss   00:46   0:00 /usr/sbin/sshd -D
root     13826  0.0  0.8  93100  6648 ?        Ss   01:26   0:00  \_ sshd: [email protected]
root     25363  0.0  0.8  92796  6700 ?        Ss   08:54   0:00  \_ sshd: vagrant [priv]
vagrant  25393  0.0  0.6  93072  4936 ?        S    08:54   0:01  |   \_ sshd: [email protected]/1
vagrant  25394  0.0  0.4  21196  3488 pts/1    Ss   08:54   0:00  |       \_ -bash
root     25402  0.0  0.4  52700  3568 pts/1    S    08:54   0:00  |           \_ sudo su -
root     25403  0.0  0.4  52284  3264 pts/1    S    08:54   0:00  |               \_ su -
root     25404  0.0  0.4  21196  3536 pts/1    S    08:54   0:00  |                   \_ -su
root     26686  6.0  4.0 570008 30980 pts/1    Sl+  09:48   0:00  |                       \_ innobackupex --encrypt=AES256 --encrypt-key=TzIZ7g+WzLt0PXWf8WDPf/sjIt7UzCKw /backup/

Idealmente, usará la clave almacenada en un archivo, pero luego hay un pequeño problema que debe tener en cuenta.

[email protected]:~# openssl rand -base64 24 > encrypt.key
[email protected]:~# innobackupex --encrypt=AES256 --encrypt-key-file=/root/encrypt.key /backup/
.
.
.
xtrabackup: using O_DIRECT
InnoDB: Number of pools: 1
encryption: unable to set libgcrypt cipher key - User defined source 1 : Invalid key length
encrypt: failed to create worker threads.
Error: failed to initialize datasink.

Usted puede preguntarse cuál es el problema. Quedará claro cuando abramos el archivo encrypt.key en un editor hexadecimal como hexedit:

00000000   6D 6B 2B 4B  66 69 55 4E  5A 49 48 77  39 42 36 72  68 70 39 79  6A 56 44 72  47 61 79 45  6F 75 6D 70  0A                                     mk+KfiUNZIHw9B6rhp9yjVDrGayEoump.

Ahora puede notar el último carácter codificado usando '0A'. Este es básicamente el carácter de avance de línea, pero se tiene en cuenta al evaluar la clave de cifrado. Una vez que lo eliminemos, finalmente podemos ejecutar la copia de seguridad.

[email protected]:~# innobackupex --encrypt=AES256 --encrypt-key-file=/root/encrypt.key /backup/
xtrabackup: recognized server arguments: --datadir=/var/lib/mysql --innodb_buffer_pool_size=185M --innodb_flush_log_at_trx_commit=2 --innodb_file_per_table=1 --innodb_data_file_path=ibdata1:100M:autoextend --innodb_read_io_threads=4 --innodb_write_io_threads=4 --innodb_doublewrite=1 --innodb_log_file_size=64M --innodb_log_buffer_size=16M --innodb_log_files_in_group=2 --innodb_flush_method=O_DIRECT --server-id=1
xtrabackup: recognized client arguments: --datadir=/var/lib/mysql --innodb_buffer_pool_size=185M --innodb_flush_log_at_trx_commit=2 --innodb_file_per_table=1 --innodb_data_file_path=ibdata1:100M:autoextend --innodb_read_io_threads=4 --innodb_write_io_threads=4 --innodb_doublewrite=1 --innodb_log_file_size=64M --innodb_log_buffer_size=16M --innodb_log_files_in_group=2 --innodb_flush_method=O_DIRECT --server-id=1 --databases-exclude=lost+found --ssl-mode=DISABLED
encryption: using gcrypt 1.6.5
181116 10:11:25 innobackupex: Starting the backup operation

IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

181116 10:11:25  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;mysql_socket=/var/lib/mysql/mysql.sock' as 'backupuser'  (using password: YES).
181116 10:11:25  version_check Connected to MySQL server
181116 10:11:25  version_check Executing a version check against the server...
181116 10:11:25  version_check Done.
181116 10:11:25 Connecting to MySQL server host: localhost, user: backupuser, password: set, port: not set, socket: /var/lib/mysql/mysql.sock
Using server version 5.7.23-23-57
innobackupex version 2.4.12 based on MySQL server 5.7.19 Linux (x86_64) (revision id: 170eb8c)
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /var/lib/mysql
xtrabackup: open files limit requested 0, set to 1024
xtrabackup: using the following InnoDB configuration:
xtrabackup:   innodb_data_home_dir = .
xtrabackup:   innodb_data_file_path = ibdata1:100M:autoextend
xtrabackup:   innodb_log_group_home_dir = ./
xtrabackup:   innodb_log_files_in_group = 2
xtrabackup:   innodb_log_file_size = 67108864
xtrabackup: using O_DIRECT
InnoDB: Number of pools: 1
181116 10:11:25 >> log scanned up to (2597648)
xtrabackup: Generating a list of tablespaces
InnoDB: Allocated tablespace ID 19 for mysql/server_cost, old maximum was 0
181116 10:11:25 [01] Encrypting ./ibdata1 to /backup/2018-11-16_10-11-25/ibdata1.xbcrypt
181116 10:11:26 >> log scanned up to (2597648)
181116 10:11:27 >> log scanned up to (2597648)
181116 10:11:28 [01]        ...done
181116 10:11:28 [01] Encrypting ./mysql/server_cost.ibd to /backup/2018-11-16_10-11-25/mysql/server_cost.ibd.xbcrypt
181116 10:11:28 [01]        ...done
181116 10:11:28 [01] Encrypting ./mysql/help_category.ibd to /backup/2018-11-16_10-11-25/mysql/help_category.ibd.xbcrypt
181116 10:11:28 [01]        ...done
181116 10:11:28 [01] Encrypting ./mysql/slave_master_info.ibd to /backup/2018-11-16_10-11-25/mysql/slave_master_info.ibd.xbcrypt
181116 10:11:28 [01]        ...done

Como resultado, terminaremos con un directorio de copia de seguridad lleno de archivos cifrados:

[email protected]:~# ls -alh /backup/2018-11-16_10-11-25/
total 101M
drwxr-x---  5 root root 4.0K Nov 16 10:11 .
drwxr-xr-x 16 root root 4.0K Nov 16 10:11 ..
-rw-r-----  1 root root  580 Nov 16 10:11 backup-my.cnf.xbcrypt
-rw-r-----  1 root root  515 Nov 16 10:11 ib_buffer_pool.xbcrypt
-rw-r-----  1 root root 101M Nov 16 10:11 ibdata1.xbcrypt
drwxr-x---  2 root root 4.0K Nov 16 10:11 mysql
drwxr-x---  2 root root  12K Nov 16 10:11 performance_schema
drwxr-x---  2 root root  12K Nov 16 10:11 sys
-rw-r-----  1 root root  113 Nov 16 10:11 xtrabackup_checkpoints
-rw-r-----  1 root root  525 Nov 16 10:11 xtrabackup_info.xbcrypt
-rw-r-----  1 root root 2.7K Nov 16 10:11 xtrabackup_logfile.xbcrypt

Xtrabackup tiene algunas otras variables que se pueden usar para ajustar el rendimiento del cifrado:

  • --encrypt-threads permite la paralelización del proceso de cifrado
  • --encrypt-chunk-size define un búfer de trabajo para el proceso de cifrado.

Si necesita descifrar los archivos, puede usar innobackupex con la opción --decrypt para eso:

[email protected]:~# innobackupex --decrypt=AES256 --encrypt-key-file=/root/encrypt.key /backup/2018-11-16_10-11-25/

Dado que xtrabackup no limpia los archivos cifrados, es posible que desee eliminarlos utilizando la siguiente frase:

for i in `find /backup/2018-11-16_10-11-25/ -iname "*\.xbcrypt"`; do rm $i ; done

Cifrado de copia de seguridad en ClusterControl

Con ClusterControl, las copias de seguridad cifradas están a solo un clic de distancia. Todos los métodos de copia de seguridad (mysqldump, xtrabackup o mariabackup) admiten el cifrado. Puede crear una copia de seguridad ad hoc o puede preparar una programación para sus copias de seguridad.

En nuestro ejemplo, elegimos un xtrabackup completo, lo almacenaremos en la instancia del controlador.

En la página siguiente habilitamos el cifrado. Como se indicó, ClusterControl creará automáticamente una clave de cifrado para nosotros. Esto es todo, cuando haga clic en el botón "Crear copia de seguridad", se iniciará un proceso.

La nueva copia de seguridad está visible en la lista de copias de seguridad. Está marcado como cifrado (el icono del candado).

Esperamos que esta publicación de blog le brinde información sobre cómo asegurarse de que sus copias de seguridad estén encriptadas correctamente.