MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

Criptografia completa do MariaDB em repouso e em trânsito para proteção máxima de dados - parte dois

Na primeira parte desta série, abordamos a configuração de criptografia em trânsito para servidores de replicação MariaDB, onde configuramos criptografias cliente-servidor e de replicação. Extraído da primeira postagem, onde configuramos parcialmente nossa criptografia completa (conforme indicado pelas setas verdes à esquerda no diagrama) e nesta postagem do blog, concluiremos a configuração de criptografia com criptografia em repouso para criar um configuração de replicação MariaDB totalmente criptografada.

O diagrama a seguir ilustra nossa configuração atual e a configuração final que alcançaremos:

Criptografia em repouso

A criptografia em repouso significa que os dados em repouso, como arquivos de dados e logs, são criptografados no disco, tornando quase impossível que alguém acesse ou roube um disco rígido e tenha acesso aos dados originais (desde que a chave esteja protegida e não armazenada localmente). A criptografia de dados em repouso, também conhecida como Transparent Data Encryption (TDE), é suportada no MariaDB 10.1 e posterior. Observe que o uso de criptografia tem uma sobrecarga de aproximadamente 5 a 10%, dependendo da carga de trabalho e do tipo de cluster.

Para MariaDB, os seguintes componentes MariaDB podem ser criptografados em repouso:

  • Arquivo de dados InnoDB (espaço de tabela compartilhado ou espaço de tabela individual, por exemplo, *.ibd e ibdata1)
  • Aria dados e arquivos de índice.
  • Registros de desfazer/refazer (arquivos de log do InnoDB, por exemplo, ib_logfile0 e ib_logfile1).
  • Registros binários/de retransmissão.
  • Arquivos e tabelas temporários.

Os seguintes arquivos não podem ser criptografados no momento:

  • Arquivo de metadados (por exemplo, arquivos .frm).
  • Log geral baseado em arquivo/log de consulta lenta. Log geral baseado em tabela/log de consulta lenta pode ser criptografado.
  • Registro de erros.

A criptografia de dados em repouso do MariaDB requer o uso de um gerenciamento de chaves e plugins de criptografia. Nesta postagem do blog, usaremos o plug-in de criptografia de gerenciamento de chave de arquivo, que é fornecido por padrão desde o MariaDB 10.1.3. Observe que há várias desvantagens ao usar este plug-in, por exemplo, a chave ainda pode ser lida pelo usuário root e MySQL, conforme explicado na página MariaDB Data-at-Rest Encryption.

Gerando arquivo de chave

Vamos criar um diretório dedicado para armazenar nosso material de criptografia em repouso:

$ mkdir -p /etc/mysql/rest
$ cd /etc/mysql/rest

Crie um arquivo-chave. Este é o núcleo da criptografia:

$ openssl rand -hex 32 > /etc/mysql/rest/keyfile

Anexar uma string "1;" como o identificador de chave no arquivo de chave:

$ echo '1;' 
sed -i '1s/^/1;/' /etc/mysql/rest/keyfile

Assim, ao ler o arquivo-chave, ele deve ficar assim:

$ cat /etc/mysql/rest/keyfile
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7

O acima significa simplesmente para o identificador de chave 1, a chave é 4eb... O arquivo de chave precisa conter duas informações para cada chave de criptografia. Primeiro, cada chave de criptografia precisa ser identificada com um número inteiro de 32 bits como identificador de chave. Segundo, a própria chave de criptografia precisa ser fornecida em formato hexadecimal. Essas duas informações precisam ser separadas por um ponto e vírgula.

Crie uma senha para criptografar a chave acima. Aqui vamos armazenar a senha dentro de um arquivo chamado "keyfile.passwd":

$ echo -n 'mySuperStrongPassword' > /etc/mysql/rest/keyfile.passwd

Você pode pular a etapa acima se quiser especificar a senha diretamente no arquivo de configuração usando a opção file_key_management_filekey. Por exemplo:file_key_management_filekey=mySuperStrongPassword

Mas neste exemplo, vamos ler a senha que está armazenada em um arquivo, portanto, temos que definir a seguinte linha no arquivo de configuração posteriormente:

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

Vamos criptografar o arquivo-chave de texto simples em outro arquivo chamado keyfile.enc, usando a senha dentro do arquivo de senha:

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

Ao listar o diretório, devemos ver estes 3 arquivos:

$ ls -1 /etc/mysql/rest/
keyfile
keyfile.enc
keyfile.passwd

O conteúdo do keyfile.enc é simplesmente uma versão criptografada do keyfile:

Para testar, podemos descriptografar o arquivo criptografado usando OpenSSL fornecendo o arquivo de senha (keyfile.passwd):

$ openssl aes-256-cbc -d -md sha1 -pass file:/etc/mysql/rest/keyfile.passwd -in /etc/mysql/rest/keyfile.enc
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7

Podemos então remover a chave simples porque vamos usar a chave criptografada (.enc) junto com o arquivo de senha:

$ rm -f /etc/mysql/encryption/keyfile

Agora podemos prosseguir para configurar a criptografia em repouso do MariaDB.

Configurando a criptografia em repouso

Temos que mover o arquivo de chave criptografada e a senha para os escravos a serem usados ​​pelo MariaDB para criptografar/descriptografar os dados. Caso contrário, uma tabela criptografada sendo copiada do mestre usando backup físico como o MariaDB Backup teria um problema de leitura pelos escravos (devido à combinação diferente de chave/senha). Backup lógico como mysqldump deve funcionar com diferentes chaves e senhas.

Nos escravos, crie um diretório para armazenar coisas de criptografia em repouso:

(slave1)$ mkdir -p /etc/mysql/rest
(slave2)$ mkdir -p /etc/mysql/rest

No mestre, copie o arquivo de chave criptografado e o arquivo de senha para os outros escravos:

(master)$ cd /etc/mysql/rest
(master)$ scp keyfile.enc keyfile.passwd [email protected]:/etc/mysql/rest/
(master)$ scp keyfile.enc keyfile.passwd [email protected]:/etc/mysql/rest/

Proteja os arquivos do acesso global e atribua o usuário "mysql" como proprietário:

$ chown mysql:mysql /etc/mysql/rest/*
$ chmod 600 /etc/mysql/rest/*

Adicione o seguinte no arquivo de configuração do MariaDB na seção [mysqld] ou [mariadb]:

# at-rest encryption
plugin_load_add              = file_key_management
file_key_management_filename = /etc/mysql/rest/keyfile.enc
file_key_management_filekey  = FILE:/etc/mysql/rest/keyfile.passwd
file_key_management_encryption_algorithm = AES_CBC

innodb_encrypt_tables            = ON
innodb_encrypt_temporary_tables  = ON
innodb_encrypt_log               = ON
innodb_encryption_threads        = 4
innodb_encryption_rotate_key_age = 1
encrypt-tmp-disk-tables          = 1
encrypt-tmp-files                = 1
encrypt-binlog                   = 1
aria_encrypt_tables              = ON

Anote a variável file_key_management_filekey, se a senha estiver em um arquivo, você deve prefixar o caminho com "FILE:". Alternativamente, você também pode especificar a string de senha diretamente (não recomendado devido à sua verbosidade):

file_key_management_filekey=mySuperStrongPassword

Reinicie o servidor MariaDB um nó por vez, começando com os escravos:

(slave1)$ systemctl restart mariadb
(slave2)$ systemctl restart mariadb
(master)$ systemctl restart mariadb

Observe o log de erros e certifique-se de que a criptografia MariaDB esteja ativada durante a inicialização:

$ tail -f /var/log/mysql/mysqld.log
...
2019-12-17  6:44:47 0 [Note] InnoDB: Encrypting redo log: 2*67108864 bytes; LSN=143311
2019-12-17  6:44:48 0 [Note] InnoDB: Starting to delete and rewrite log files.
2019-12-17  6:44:48 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 67108864 bytes
2019-12-17  6:44:48 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 67108864 bytes
2019-12-17  6:44:48 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2019-12-17  6:44:48 0 [Note] InnoDB: New log files created, LSN=143311
2019-12-17  6:44:48 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2019-12-17  6:44:48 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2019-12-17  6:44:48 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2019-12-17  6:44:48 0 [Note] InnoDB: Waiting for purge to start
2019-12-17  6:44:48 0 [Note] InnoDB: 10.4.11 started; log sequence number 143311; transaction id 222
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #1 encryption thread id 139790011840256 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #2 encryption thread id 139790003447552 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #3 encryption thread id 139789995054848 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #4 encryption thread id 139789709866752 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2019-12-17  6:44:48 0 [Note] Plugin 'FEEDBACK' is disabled.
2019-12-17  6:44:48 0 [Note] Using encryption key id 1 for temporary files
...

Você deve ver linhas indicando a inicialização da criptografia no log de erros. Neste ponto, a maior parte da configuração de criptografia está concluída.

Testando sua criptografia

Crie um banco de dados de teste para testar no mestre:

(master)MariaDB> CREATE SCHEMA sbtest;
(master)MariaDB> USE sbtest;

Crie uma tabela padrão sem criptografia e insira uma linha:

MariaDB> CREATE TABLE tbl_plain (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255));
MariaDB> INSERT INTO tbl_plain SET data = 'test data';

Podemos ver os dados armazenados em texto não criptografado ao navegar no arquivo de dados do InnoDB usando uma ferramenta hexdump:

$ xxd /var/lib/mysql/sbtest/tbl_plain.ibd | less
000c060: 0200 1c69 6e66 696d 756d 0002 000b 0000  ...infimum......
000c070: 7375 7072 656d 756d 0900 0000 10ff f180  supremum........
000c080: 0000 0100 0000 0000 0080 0000 0000 0000  ................
000c090: 7465 7374 2064 6174 6100 0000 0000 0000  test data.......
000c0a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Crie uma tabela criptografada e insira uma linha:

MariaDB> CREATE TABLE tbl_enc (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255)) ENCRYPTED=YES;
MariaDB> INSERT INTO tbl_enc SET data = 'test data';

Não podemos dizer o que está armazenado no arquivo de dados InnoDB para tabelas criptografadas:

$ xxd /var/lib/mysql/sbtest/tbl_enc.ibd | less
000c060: 0c2c 93e4 652e 9736 e68a 8b69 39cb 6157  .,..e..6...i9.aW
000c070: 3cd1 581c 7eb9 84ca d792 7338 521f 0639  <.X.~.....s8R..9
000c080: d279 9eb3 d3f5 f9b0 eccb ed05 de16 f3ac  .y..............
000c090: 6d58 5519 f776 8577 03a4 fa88 c507 1b31  mXU..v.w.......1
000c0a0: a06f 086f 28d9 ac17 8923 9412 d8a5 1215  .o.o(....#......

Observe que o arquivo de metadados tbl_enc.frm não é criptografado em repouso. Apenas o arquivo de dados InnoDB (.ibd) é criptografado.

Ao comparar os logs binários ou de retransmissão "simples", podemos ver claramente o conteúdo deles usando a ferramenta hexdump:

$ xxd binlog.000002 | less
0000560: 0800 0800 0800 0b04 726f 6f74 096c 6f63  ........root.loc
0000570: 616c 686f 7374 0047 5241 4e54 2052 454c  alhost.GRANT REL
0000580: 4f41 442c 4c4f 434b 2054 4142 4c45 532c  OAD,LOCK TABLES,
0000590: 5245 504c 4943 4154 494f 4e20 434c 4945  REPLICATION CLIE
00005a0: 4e54 2c45 5645 4e54 2c43 5245 4154 4520  NT,EVENT,CREATE
00005b0: 5441 424c 4553 5041 4345 2c50 524f 4345  TABLESPACE,PROCE
00005c0: 5353 2c43 5245 4154 452c 494e 5345 5254  SS,CREATE,INSERT
00005d0: 2c53 454c 4543 542c 5355 5045 522c 5348  ,SELECT,SUPER,SH
00005e0: 4f57 2056 4945 5720 4f4e 202a 2e2a 2054  OW VIEW ON *.* T

Enquanto para um log binário criptografado, o conteúdo parece sem sentido:

$ xxd binlog.000004 | less
0000280: 4a1d 1ced 2f1b db50 016a e1e9 1351 84ba  J.../..P.j...Q..
0000290: 38b6 72e7 8743 7713 afc3 eecb c36c 1b19  8.r..Cw......l..
00002a0: 7b3f 6176 208f 0000 00dc 85bf 6768 e7c6  {?av .......gh..
00002b0: 6107 5bea 241c db12 d50c 3573 48e5 3c3d  a.[.$.....5sH.<=
00002c0: 3179 1653 2449 d408 1113 3e25 d165 c95b  1y.S$I....>%.e.[
00002d0: afb0 6778 4b26 f672 1bc7 567e da96 13f5  ..gxK&.r..V~....
00002e0: 2ac5 b026 3fb9 4b7a 3ef4 ab47 6c9f a686  *..&?.Kz>..Gl...

Criptografando Tabelas Aria

Para o mecanismo de armazenamento Aria, ele não suporta a opção ENCRYPTED na instrução CREATE/ALTER, pois segue a opção global aria_encrypt_tables. Portanto, ao criar uma tabela Aria, basta criar a tabela com a opção ENGINE=Aria:

MariaDB> CREATE TABLE tbl_aria_enc (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255)) ENGINE=Aria;
MariaDB> INSERT INTO tbl_aria_enc(data) VALUES ('test data');
MariaDB> FLUSH TABLE tbl_aria_enc;

Podemos então verificar o conteúdo do arquivo de dados da tabela (tbl_aria_enc.MAD) ou arquivo de índice (tbl_aria_enc.MAI) com a ferramenta hexdump. Para criptografar uma tabela Aria existente, a tabela precisa ser reconstruída:

MariaDB> ALTER TABLE db.aria_table ENGINE=Aria ROW_FORMAT=PAGE;

Esta instrução faz com que Aria reconstrua a tabela usando a opção de tabela ROW_FORMAT. No processo, com a nova configuração padrão, ele criptografa a tabela ao gravar no disco.

Criptografando log geral/log de consulta lenta

Para criptografar logs de consultas gerais e lentas, podemos definir a opção log_output do MariaDB como 'TABLE' em vez do 'FILE' padrão:

MariaDB> SET GLOBAL log_ouput = 'TABLE';

No entanto, por padrão, o MariaDB criará as tabelas necessárias usando o mecanismo de armazenamento CSV, que não é criptografado pelo MariaDB. Nenhum mecanismo além de CSV, MyISAM ou Aria é legal para as tabelas de log. O truque é reconstruir a tabela CSV padrão com o mecanismo de armazenamento Aria, desde que a opção aria_encrypt_tables esteja definida como ON. No entanto, a respectiva opção de log deve ser desativada para que a alteração da tabela seja bem-sucedida.

Assim, as etapas para criptografar a tabela de log geral são:

MariaDB> SET GLOBAL general_log = OFF;
MariaDB> ALTER TABLE mysql.general_log ENGINE=Aria;
MariaDB> SET GLOBAL general_log = ON;

Da mesma forma, para log de consulta lenta:

MariaDB> SET GLOBAL slow_query_log = OFF;
MariaDB> ALTER TABLE mysql.slow_log ENGINE=Aria;
MariaDB> SET GLOBAL slow_query_log = ON;

Verifique a saída dos logs gerais no servidor:

MariaDB> SELECT * FROM mysql.general_log;
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
| event_time                 | user_host                 | thread_id | server_id | command_type | argument                     |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
| 2019-12-17 07:45:53.109558 | root[root] @ localhost [] |        19 |     28001 |        Query | select * from sbtest.tbl_enc |
| 2019-12-17 07:45:55.504710 | root[root] @ localhost [] |        20 |     28001 |        Query | select * from general_log    |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+

Além do conteúdo criptografado do arquivo de dados Aria dentro do diretório de dados usando a ferramenta hexdump:

$ xxd /var/lib/mysql/mysql/general_log.MAD | less
0002040: 1d45 820d 7c53 216c 3fc6 98a6 356e 1b9e  .E..|S!l?...5n..
0002050: 6bfc e193 7509 1fa7 31e2 e22a 8f06 3c6f  k...u...1..*..<o
0002060: ae71 bb63 e81b 0b08 7120 0c99 9f82 7c33  .q.c....q ....|3
0002070: 1117 bc02 30c1 d9a7 c732 c75f 32a6 e238  ....0....2._2..8
0002080: d1c8 5d6f 9a08 455a 8363 b4f4 5176 f8a1  ..]o..EZ.c..Qv..
0002090: 1bf8 113c 9762 3504 737e 917b f260 f88c  ...<.b5.s~.{.`..
00020a0: 368e 336f 9055 f645 b636 c5c1 debe fbe7  6.3o.U.E.6......
00020b0: d01e 028f 8b75 b368 0ef0 8889 bb63 e032  .....u.h.....c.2

A criptografia em repouso do MariaDB está concluída. Combine isso com a criptografia em trânsito que fizemos no primeiro post, nossa arquitetura final agora está assim:

Conclusão


Agora é possível proteger totalmente seus bancos de dados MariaDB por meio de criptografia para proteção contra violação ou roubo físico e virtual. O ClusterControl também pode ajudá-lo a manter esse tipo de segurança e você pode baixá-lo gratuitamente aqui.