A criptografia é um dos recursos de segurança mais importantes para manter seus dados o mais seguros possível. Dependendo dos dados que você está manipulando, nem sempre é uma obrigação, mas você deve pelo menos considerá-lo como uma melhoria de segurança em sua organização e, na verdade, é recomendável evitar roubo de dados ou acesso não autorizado.
Neste blog, descreveremos dois tipos básicos de criptografia e como configurá-la em um servidor MariaDB.
O que é criptografia de dados?
Existem dois tipos básicos de criptografia de dados:em repouso e em trânsito. Vejamos o que significam.
Criptografia de dados em repouso
Os dados armazenados em um sistema são conhecidos como dados em repouso. A criptografia desses dados consiste em usar um algoritmo para converter texto ou código em ilegível. Você deve ter uma chave de criptografia para decodificar os dados criptografados.
A criptografia de um banco de dados inteiro deve ser feita com cautela, pois pode resultar em um sério impacto no desempenho. Portanto, é aconselhável criptografar apenas campos ou tabelas individuais.
A criptografia de dados em repouso protege os dados contra roubo físico de discos rígidos ou acesso não autorizado ao armazenamento de arquivos. Essa criptografia também está em conformidade com os regulamentos de segurança de dados, especialmente se houver dados financeiros ou de saúde armazenados no sistema de arquivos.
Criptografia de dados em trânsito
Os dados transferidos ou movimentados entre transações são conhecidos como dados em trânsito. Os dados que se movem entre o servidor e o cliente durante a navegação nas páginas da Web são um bom exemplo desse tipo de dados.
Como está sempre em movimento, precisa ser protegido com criptografia adequada para evitar qualquer roubo ou alteração dos dados antes de chegar ao seu destino.
A situação ideal para proteger os dados em trânsito é ter os dados criptografados antes de serem movidos e só são descriptografados quando chegam ao destino final.
Criptografia de dados em repouso MariaDB
A criptografia de tabelas e tablespaces foi adicionada no MariaDB a partir da versão 10.1 e suporta criptografia para mecanismos de armazenamento XtraDB, InnoDB e Aria, e também para logs binários.
Você pode escolher diferentes maneiras de criptografar:
- Todas as tabelas
- Tabelas individuais
- Tudo, exceto tabelas individuais
De acordo com a documentação, o uso de criptografia tem uma sobrecarga de aproximadamente 3-5%, por isso é importante ter um ambiente de teste para estressá-lo e ver como ele responde, para evitar problemas na produção.
Como configurar a criptografia de dados em repouso no MariaDB
Vamos verificar uma tabela “cidade” existente em um banco de dados MariaDB:
$ strings city.ibd |head
infimum
supremum
infimum
supremum
3ABW
3KHM
infimum
supremum
Kabul AFGKabol
Qandahar AFGQandahar
Como você pode ver, você pode ler dados de lá sem nenhum problema usando o comando strings do Linux, por exemplo. Agora, vamos ver como criptografá-lo.
Gere uma chave de criptografia usando o comando openssl rand:
$ mkdir -p /etc/mysql/encryption
$ for i in {1..4}; do openssl rand -hex 32 >> /etc/mysql/encryption/keyfile; done;
Edite o arquivo gerado /etc/mysql/encryption/keyfile e adicione os IDs de chave que serão referenciados ao criar tabelas criptografadas. O formato deve ser o seguinte:
<encryption_key_id1>;<hex-encoded_encryption_key1>
<encryption_key_id2>;<hex-encoded_encryption_key2>
Você pode editá-lo usando o comando sed linux desta forma:
$ for i in {1..4}; do sed -i -e "$i s/^/$i;/" keyfile; done
Então o arquivo deve ser algo assim:
$ cat /etc/mysql/encryption/keyfile
1;f237fe72e16206c0b0f6f43c3b3f4accc242564d77f5fe17bb621de388c193af
2;0c0819a10fb366a5ea657a71759ee6a950ae8f25a5ba7400a91f59b63683edc5
3;ac9ea3a839596dbf52492d9ab6b180bf11a35f44995b2ed752c370d920a10169
4;72afc936e16a8df05cf994c7902e588de0d11ca7301f9715d00930aa7d5ff8ab
Agora, gere uma senha aleatória usando o comando openssl semelhante que você viu anteriormente:
$ openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key
Antes de prosseguir para a próxima etapa, é importante conhecer os seguintes detalhes sobre a criptografia do arquivo de chave:
- O único algoritmo que o MariaDB atualmente suporta para criptografar o arquivo de chave é o modo Cipher Block Chaining (CBC) do Advanced Encryption Standard (AES).
- O tamanho da chave de criptografia pode ser 128 bits, 192 bits ou 256 bits.
- A chave de criptografia é criada a partir do hash SHA-1 da senha de criptografia.
- A senha de criptografia tem um comprimento máximo de 256 caracteres.
Agora, para criptografar o arquivo de chave usando o comando openssl enc, execute o seguinte 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, você precisa adicionar os seguintes parâmetros em seu arquivo de configuração my.cnf (localizado em /etc/ no sistema operacional baseado em RedHat ou /etc/mysql/ no sistema operacional baseado em 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
…
E reinicie o serviço MariaDB para fazer as alterações:
$ systemctl restart mariadb
Neste ponto, tudo está pronto para usar o recurso de criptografia. Vamos criptografar a mesma tabela que mostramos anteriormente, “cidade”. Para isso, você precisa usar a instrução ALTER TABLE configurando o parâmetro ENCRYPTED em YES:
MariaDB [world]> ALTER TABLE city ENCRYPTED=YES;
Query OK, 0 rows affected (0.483 sec)
Records: 0 Duplicates: 0 Warnings: 0
Agora, se você tentar acessar a tabela diretamente do sistema de arquivos, verá algo assim:
$ strings city.ibd |head
PU%O
!ybN)b
9,{9WB4
T3uG:
?oiN
,35sz
8g)Q
o(o
q_A1
k=-w
Como você pode ver, a tabela está ilegível. Você também pode especificar o ID da chave de criptografia adicionando o parâmetro ENCRYPTION_KEY_ID = Novas tabelas serão criptografadas por padrão quando definirmos o parâmetro innodb_encrypt_tables em ON no arquivo de configuração my.cnf. MariaDB permite criptografar dados em trânsito entre o servidor e os clientes usando o protocolo Transport Layer Security (TLS), anteriormente conhecido como Secure Socket Layer ou SSL. Em primeiro lugar, você precisa garantir que seu servidor MariaDB foi compilado com suporte a TLS. Você pode verificar isso executando a seguinte instrução SHOW GLOBAL VARIABLES: E verifique se não está em uso no momento usando a instrução SHOW VARIABLES: Você também pode verificar o status SSL usando o comando status MariaDB: Vamos criar o diretório certs para armazenar todos os certificados: Agora, vamos gerar os certificados de CA que serão configurados para criptografar a conexão: Este último comando solicitará que você preencha as seguintes informações: Agora, você precisa gerar os certificados do servidor: Este comando solicitará que você preencha as mesmas informações anteriores mais uma senha de certificado opcional. E, finalmente, você precisa gerar os certificados do cliente: Isso também solicitará que você preencha as informações e uma senha de certificado opcional. Certifique-se de estar usando um nome comum diferente em cada certificado, caso contrário não funcionará e você receberá uma mensagem como: Neste momento, você terá algo assim: E você pode validar os certificados usando o seguinte comando: Então agora vamos configurá-lo no arquivo de configuração my.cnf (localizado em /etc/ no sistema operacional baseado em RedHat ou /etc/mysql/ no sistema operacional baseado em Debian): Certifique-se de estar adicionando-o na seção correspondente (mysqld e client-mariadb). Altere o proprietário do certificado e reinicie o serviço de banco de dados: Depois disso, se você der uma olhada na saída SHOW VARIABLES, você deve ter isto: Agora, vamos criar um usuário com o parâmetro REQUIRE SSL para usá-lo: Se você usar este usuário para acessar o banco de dados e verificar o comando status, verá o SSL em uso: Outra maneira, e até mais fácil, de habilitar SSL em seu banco de dados MariaDB é usando ClusterControl. Vamos supor que você tenha o ClusterControl instalado e esteja gerenciando seu banco de dados MariaDB usando-o, então vá para ClusterControl -> Select your MariaDB Cluster -> Security -> SSL Encryption -> Enable. E pronto, você terá sua criptografia SSL habilitada em seu banco de dados MariaDB sem nenhuma tarefa manual. Existem algumas limitações relacionadas à criptografia em repouso do MariaDB a serem consideradas: Proteger dados em trânsito é tão importante quanto proteger dados em repouso e, mesmo que não seja uma obrigação em sua organização, considere aplicá-lo, pois pode ajudá-lo a evitar dados roubo ou acesso não autorizado.
Criptografia de dados em trânsito MariaDB
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)
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)
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
--------------
Como configurar a criptografia de dados em trânsito no MariaDB
$ mkdir -p /etc/mysql/certs
$ openssl genrsa 2048 > ca-key.pem
$ openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
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 []:
$ openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem
$ 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
$ openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem
$ 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
ERROR 2026 (HY000): SSL connection error: self signed certificate
$ 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
$ openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
[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
$ chown mysql.mysql /etc/mysql/certs/
$ systemctl restart mariadb
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)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 's9s'@'%' IDENTIFIED BY 'root123' REQUIRE SSL;
Query OK, 0 rows affected (0.005 sec)
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
--------------
Como habilitar a criptografia SSL com ClusterControl
Limitações de criptografia em repouso no MariaDB
Conclusão
O MariaDB tem uma maneira bem fácil de implementá-lo seguindo as etapas mencionadas anteriormente, mas é ainda mais fácil usar o ClusterControl com certeza.