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

Fundamentos del cifrado de la base de datos del servidor MariaDB

El cifrado es una de las características de seguridad más importantes para mantener sus datos lo más seguros posible. Dependiendo de los datos que esté manejando, no siempre es obligatorio, pero al menos debería considerarlo como una mejora de seguridad en su organización de todos modos, y en realidad se recomienda para evitar el robo de datos o el acceso no autorizado.

En este blog, describiremos dos tipos básicos de cifrado y cómo configurarlo en un servidor MariaDB.

¿Qué es el cifrado de datos?

Hay dos tipos básicos de cifrado de datos:en reposo y en tránsito. Veamos qué significan.

Cifrado de datos en reposo

Los datos almacenados en un sistema se conocen como datos en reposo. El cifrado de estos datos consiste en utilizar un algoritmo para convertir texto o código en ilegible. Debe tener una clave de cifrado para decodificar los datos cifrados.

El cifrado de una base de datos completa debe realizarse con precaución, ya que puede tener un impacto grave en el rendimiento. Por lo tanto, es aconsejable cifrar solo campos o tablas individuales.

El cifrado de datos en reposo protege los datos del robo físico de los discos duros o del acceso no autorizado al almacenamiento de archivos. Este cifrado también cumple con las normas de seguridad de datos, especialmente si hay datos financieros o de salud almacenados en el sistema de archivos.

Cifrado de datos en tránsito

Los datos transferidos o que se mueven entre transacciones se conocen como datos en tránsito. Los datos que se mueven entre el servidor y el cliente mientras se navega por páginas web son un buen ejemplo de este tipo de datos.

Dado que siempre está en movimiento, debe protegerse con el cifrado adecuado para evitar cualquier robo o alteración de los datos antes de que lleguen a su destino.

La situación ideal para proteger los datos en tránsito es cifrar los datos antes de que se muevan y solo se descifran cuando llegan al destino final.

Cifrado de datos en reposo MariaDB

El cifrado de tablas y espacios de tablas se agregó en MariaDB a partir de la versión 10.1 y admite el cifrado para motores de almacenamiento XtraDB, InnoDB y Aria, y también para registros binarios.

Puede elegir diferentes formas de cifrar:

  • Todas las tablas
  • Mesas individuales
  • Todo, excepto tablas individuales

Según la documentación, el uso de cifrado tiene una sobrecarga de aproximadamente 3-5%, por lo que es importante tener un entorno de prueba para estresarlo y ver cómo responde, para evitar problemas en producción.

Cómo configurar el cifrado de datos en reposo en MariaDB

Veamos una tabla de "ciudad" existente en una base de datos MariaDB:

$ strings city.ibd |head

infimum

supremum

infimum

supremum

3ABW

3KHM

infimum

supremum

Kabul                              AFGKabol

Qandahar                           AFGQandahar

Como puede ver, puede leer datos desde allí sin ningún problema utilizando el comando strings de Linux, por ejemplo. Ahora, veamos cómo cifrarlo.

Generar claves de cifrado usando el comando rand de openssl:

$ mkdir -p /etc/mysql/encryption

$ for i in {1..4}; do openssl rand -hex 32 >> /etc/mysql/encryption/keyfile;  done;

Edite el archivo generado /etc/mysql/encryption/keyfile y agregue los ID de clave a los que se hará referencia al crear tablas cifradas. El formato debe ser el siguiente:

<encryption_key_id1>;<hex-encoded_encryption_key1>

<encryption_key_id2>;<hex-encoded_encryption_key2>

Puedes editarlo usando el comando sed linux de esta manera:

$ for i in {1..4}; do sed -i -e "$i s/^/$i;/" keyfile; done

Entonces el archivo debería ser algo como esto:

$ cat /etc/mysql/encryption/keyfile

1;f237fe72e16206c0b0f6f43c3b3f4accc242564d77f5fe17bb621de388c193af

2;0c0819a10fb366a5ea657a71759ee6a950ae8f25a5ba7400a91f59b63683edc5

3;ac9ea3a839596dbf52492d9ab6b180bf11a35f44995b2ed752c370d920a10169

4;72afc936e16a8df05cf994c7902e588de0d11ca7301f9715d00930aa7d5ff8ab

Ahora, genera una contraseña aleatoria usando el comando openssl similar que viste antes:

$ openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key

Antes de continuar con el siguiente paso, es importante conocer los siguientes detalles sobre el cifrado del archivo clave:

  • El único algoritmo que MariaDB admite actualmente para cifrar el archivo clave es el modo Cipher Block Chaining (CBC) del estándar de cifrado avanzado (AES).
  • El tamaño de la clave de cifrado puede ser de 128 bits, 192 bits o 256 bits.
  • La clave de cifrado se crea a partir del hash SHA-1 de la contraseña de cifrado.
  • La contraseña de cifrado tiene una longitud máxima de 256 caracteres.

Ahora, para encriptar el archivo clave usando el comando openssl enc, ejecute el siguiente comando:

$ openssl enc -aes-256-cbc -md sha1 -pass file:/etc/mysql/encryption/keyfile.key -in /etc/mysql/encryption/keyfile -out /etc/mysql/encryption/keyfile.enc

Finalmente, debe agregar los siguientes parámetros en su archivo de configuración my.cnf (ubicado en /etc/ en el sistema operativo basado en RedHat o /etc/mysql/ en el sistema operativo basado en Debian):

[mysqld]

…

#################### DATABASE ENCRYPTION ####################

plugin_load_add = file_key_management

file_key_management_filename = /etc/mysql/encryption/keyfile.enc

file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key

file_key_management_encryption_algorithm = aes_cbc

encrypt_binlog = 1



innodb_encrypt_tables = ON

innodb_encrypt_log = ON

innodb_encryption_threads = 4

innodb_encryption_rotate_key_age = 0 

…

Y reinicie el servicio MariaDB para tomar los cambios:

$ systemctl restart mariadb

En este punto, todo está listo para usar la función de encriptación. Codifiquemos la misma tabla que mostramos anteriormente, "ciudad". Para esto, debe usar la instrucción ALTER TABLE configurando el parámetro ENCRYPTED en SÍ:

MariaDB [world]> ALTER TABLE city ENCRYPTED=YES;

Query OK, 0 rows affected (0.483 sec)

Records: 0  Duplicates: 0  Warnings: 0

Ahora, si intenta acceder a la tabla directamente desde el sistema de archivos, verá algo como esto:

$ strings city.ibd |head

PU%O

!ybN)b

9,{9WB4

T3uG:

?oiN

,35sz

8g)Q

o(o

q_A1

k=-w

Como puede ver, la tabla es ilegible. También puede especificar el ID de clave de cifrado agregando el parámetro ENCRYPTION_KEY_ID = en el comando MySQL, donde es el número de ID del archivo de claves creado previamente.

Las tablas nuevas se cifrarán de forma predeterminada cuando establezcamos el parámetro innodb_encrypt_tables en ON en el archivo de configuración my.cnf.

Cifrado de datos en tránsito MariaDB

MariaDB le permite cifrar los datos en tránsito entre el servidor y los clientes utilizando el protocolo de seguridad de la capa de transporte (TLS), anteriormente conocido como capa de conexión segura o SSL.

En primer lugar, debe asegurarse de que su servidor MariaDB se compiló con soporte TLS. Puede verificar esto ejecutando la siguiente instrucción SHOW GLOBAL VARIABLES:

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'version_ssl_library';

+---------------------+----------------------------+

| Variable_name       | Value                      |

+---------------------+----------------------------+

| version_ssl_library | OpenSSL 1.1.1  11 Sep 2018 |

+---------------------+----------------------------+

1 row in set (0.001 sec)

Y verifique si no está actualmente en uso usando la instrucción SHOW VARIABLES:

MariaDB [(none)]> SHOW VARIABLES LIKE '%ssl%';

+---------------------+----------------------------+

| Variable_name       | Value                      |

+---------------------+----------------------------+

| have_openssl        | YES                        |

| have_ssl            | DISABLED                   |

| ssl_ca              |                            |

| ssl_capath          |                            |

| ssl_cert            |                            |

| ssl_cipher          |                            |

| ssl_crl             |                            |

| ssl_crlpath         |                            |

| ssl_key             |                            |

| version_ssl_library | OpenSSL 1.1.1  11 Sep 2018 |

+---------------------+----------------------------+

10 rows in set (0.001 sec)

También puede verificar el estado SSL usando el comando status MariaDB:

MariaDB [(none)]> status

--------------

mysql  Ver 15.1 Distrib 10.4.13-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

Connection id: 22

Current database:

Current user: [email protected]

SSL: Not in use

Current pager: stdout

Using outfile: ''

Using delimiter: ;

Server: MariaDB

Server version: 10.4.13-MariaDB-1:10.4.13+maria~bionic-log mariadb.org binary distribution

Protocol version: 10

Connection: Localhost via UNIX socket

Server characterset: latin1

Db     characterset: latin1

Client characterset: utf8

Conn.  characterset: utf8

UNIX socket: /var/lib/mysql/mysql.sock

Uptime: 4 hours 28 min 25 sec

Threads: 11  Questions: 111668  Slow queries: 0  Opens: 92  Flush tables: 1  Open tables: 85  Queries per second avg: 6.933

--------------

Cómo configurar el cifrado de datos en tránsito en MariaDB

Vamos a crear el directorio de certificados para almacenar todos los certificados:

$ mkdir -p /etc/mysql/certs

Ahora, generemos los certificados de CA que se configurarán para cifrar la conexión:

$ openssl genrsa 2048 > ca-key.pem

$ openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem

Este último comando le pedirá que complete la siguiente información:

Country Name (2 letter code) [AU]:

State or Province Name (full name) [Some-State]:

Locality Name (eg, city) []:

Organization Name (eg, company) [Internet Widgits Pty Ltd]:

Organizational Unit Name (eg, section) []:

Common Name (e.g. server FQDN or YOUR name) []:

Email Address []:

Ahora, necesita generar los certificados del servidor:

$ openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem

Este comando le pedirá que complete la misma información que antes más una contraseña de certificado opcional.

$ openssl rsa -in server-key.pem -out server-key.pem

$ openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

Y finalmente, necesita generar los certificados de cliente:

$ openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem

Esto también le pedirá que complete la información y una contraseña de certificado opcional.

$ openssl rsa -in client-key.pem -out client-key.pem

$ openssl x509 -req -in client-req.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem

Asegúrese de estar usando un nombre común diferente en cada certificado; de lo contrario, no funcionará y recibirá un mensaje como:

ERROR 2026 (HY000): SSL connection error: self signed certificate

En este momento, tendrá algo como esto:

$ ls /etc/mysql/certs/

ca-cert.pem  ca-key.pem  client-cert.pem  client-key.pem  client-req.pem  server-cert.pem  server-key.pem  server-req.pem

Y puede validar los certificados usando el siguiente comando:

$ openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem

server-cert.pem: OK

client-cert.pem: OK

Así que ahora vamos a configurarlo en el archivo de configuración my.cnf (ubicado en /etc/ en el sistema operativo basado en RedHat o /etc/mysql/ en el sistema operativo basado en Debian):

[mysqld]

ssl_ca=/etc/mysql/certs/ca-cert.pem

ssl_cert=/etc/mysql/certs/server-cert.pem

ssl_key=/etc/mysql/certs/server-key.pem



[client-mariadb]

ssl_ca =/etc/mysql/certs/ca-cert.pem

ssl_cert=/etc/mysql/certs/client-cert.pem

ssl_key=/etc/mysql/certs/client-key.pem

Asegúrese de agregarlo en la sección correspondiente (mysqld y client-mariadb).

Cambie el propietario del certificado y reinicie el servicio de la base de datos:

$ chown mysql.mysql /etc/mysql/certs/

$ systemctl restart mariadb

Después de esto, si echa un vistazo a la salida MOSTRAR VARIABLES, debería tener esto:

MariaDB [(none)]> SHOW VARIABLES LIKE '%ssl%';

+---------------------+----------------------------------+

| Variable_name       | Value                            |

+---------------------+----------------------------------+

| have_openssl        | YES                              |

| have_ssl            | YES                              |

| ssl_ca              | /etc/mysql/certs/ca-cert.pem     |

| ssl_capath          |                                  |

| ssl_cert            | /etc/mysql/certs/server-cert.pem |

| ssl_cipher          |                                  |

| ssl_crl             |                                  |

| ssl_crlpath         |                                  |

| ssl_key             | /etc/mysql/certs/server-key.pem  |

| version_ssl_library | OpenSSL 1.1.1  11 Sep 2018       |

+---------------------+----------------------------------+

10 rows in set (0.001 sec)

Ahora, vamos a crear un usuario con el parámetro REQUIRE SSL para usarlo:

MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 's9s'@'%' IDENTIFIED BY 'root123' REQUIRE SSL;

Query OK, 0 rows affected (0.005 sec)

Si usa este usuario para acceder a la base de datos y verifica el comando de estado, verá el SSL en uso:

MariaDB [(none)]> status

--------------

mysql  Ver 15.1 Distrib 10.4.13-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

Connection id: 15

Current database:

Current user: [email protected]

SSL: Cipher in use is TLS_AES_256_GCM_SHA384

Current pager: stdout

Using outfile: ''

Using delimiter: ;

Server: MariaDB

Server version: 10.4.13-MariaDB-1:10.4.13+maria~bionic-log mariadb.org binary distribution

Protocol version: 10

Connection: 127.0.0.1 via TCP/IP

Server characterset: latin1

Db     characterset: latin1

Client characterset: utf8

Conn.  characterset: utf8

TCP port: 3306

Uptime: 16 sec

Threads: 11  Questions: 136  Slow queries: 0  Opens: 17  Flush tables: 1  Open tables: 11  Queries per second avg: 8.500

--------------

Cómo habilitar el cifrado SSL con ClusterControl

Otra forma, e incluso más fácil, de habilitar SSL en su base de datos MariaDB es mediante el uso de ClusterControl. Asumiremos que tiene instalado ClusterControl y que está administrando su base de datos MariaDB usándola, así que vaya a ClusterControl -> Seleccione su clúster MariaDB -> Seguridad -> Cifrado SSL -> Habilitar.

Y listo, tendrás tu encriptación SSL habilitada en tu base de datos MariaDB sin ninguna tarea manual.

Limitaciones de cifrado en reposo en MariaDB

Hay algunas limitaciones relacionadas con el cifrado en reposo de MariaDB que se deben tener en cuenta:

  • Los metadatos (por ejemplo, archivos .frm) y los datos enviados al cliente no están encriptados.
  • Solo el servidor MariaDB sabe cómo descifrar los datos, en particular
    • mysqlbinlog puede leer registros binarios encriptados solo cuando se usa --read-from-remote-server.
    • Percona XtraBackup no puede realizar copias de seguridad de instancias que utilizan InnoDB encriptado. Sin embargo, Mariabackup puede realizar copias de seguridad de instancias cifradas.
  • El gcache de Galera basado en disco no está encriptado en la versión comunitaria de MariaDB Server, sin embargo, este archivo está encriptado en MariaDB Enterprise Server 10.4.
  • El complemento de auditoría no puede crear una salida cifrada. Envíelo a syslog y configure la protección allí.
  • El registro de consultas generales basado en archivos y el registro de consultas lentas no se pueden cifrar.
  • El registro de Aria no está cifrado. Esto afecta solo a las tablas Aria no temporales.
  • El registro de errores de MariaDB no está cifrado. El registro de errores puede contener texto de consulta y datos en algunos casos, incluidos bloqueos, fallas de aserción y casos en los que InnoDB/XtraDB escribe la salida del monitor en el registro para ayudar en la depuración. También se puede enviar a syslog si es necesario.

Conclusión

La protección de los datos en tránsito es tan importante como la protección de los datos en reposo, e incluso si no es una obligación en su organización, debe considerar aplicarla, ya que puede ayudarlo a evitar que los datos robo o acceso no autorizado.

MariaDB tiene una manera bastante fácil de implementarlo siguiendo los pasos mencionados anteriormente, pero seguro que es aún más fácil usando ClusterControl.