Um dos maiores fatores e fundamentos da governança de dados é a segurança. É uma boa prática ter a segurança do banco de dados implementada sempre que seu gerenciamento de dados estiver envolvido para consumo corporativo ou em massa.
A segurança dos dados é um dos aspectos mais significativos da administração de um banco de dados. Ele desempenha um papel crítico para o qual todo gerenciamento de banco de dados deve implementar. Quando implementado e feito corretamente, o resultado deve melhorar não apenas a segurança dos dados, mas também afetar a estabilidade do sistema, melhorar o ciclo de vida do desenvolvimento, aumentar a conformidade dos dados e aumentar a conscientização sobre a segurança até o nível de sua equipe. Todo mundo não quer que seus dados acabem nas mãos erradas. Se os dados forem violados, isso não apenas colocará em risco a confidencialidade e a integridade de seus dados, mas também deixará sua organização aberta a riscos financeiros significativos. Mesmo para uma simples implementação de gerenciamento de banco de dados, se você descobrir que alguém já invadiu seu sistema, a sensação de estar inseguro e com medo das consequências que isso trará a você é totalmente desconfortável.
Determinar se sua conexão com o servidor MySQL é segura depende de quão seguramente o MySQL transmite dados em trânsito. Com uma conexão não criptografada entre o cliente MySQL e o servidor, alguém com acesso à rede pode observar todo o seu tráfego e inspecionar os dados enviados ou recebidos entre cliente e servidor.
Quando você deve mover informações em uma rede de forma segura, uma conexão não criptografada é inaceitável. Para tornar qualquer tipo de dado ilegível, use criptografia. Os algoritmos de criptografia devem incluir elementos de segurança para resistir a muitos tipos de ataques conhecidos, como alterar a ordem das mensagens criptografadas ou reproduzir dados duas vezes.
Mas meu MySQL está seguro, certo?
Acreditar que seu MySQL está seguro sem determinar suas verificações de estabilidade e vulnerabilidade é como uma religião. Você tende a acreditar mesmo sem ver, mesmo sem tocá-lo. O problema é que o MySQL é uma tecnologia e sua existência não é baseada em pensamentos abstratos. Tem de ser testado, tem de ser comprovado, requer segurança e segue as melhores práticas que também foram testadas por outros.
Determinar se suas conexões de servidor MySQL, ou seja, em trânsito, são seguras ou se estão criptografadas, depende de "como você configurou seu banco de dados?" ou "quem configurou seu banco de dados?".
O MySQL oferece suporte a conexões criptografadas entre clientes e o servidor usando o protocolo TLS (Transport Layer Security). O TLS às vezes é chamado de SSL (Secure Sockets Layer), mas o MySQL na verdade não usa o protocolo SSL para conexões criptografadas porque sua criptografia é fraca e o SSL já foi preterido em favor do TLS. O TLS usa algoritmos de criptografia para garantir que os dados recebidos por uma rede pública sejam confiáveis. Possui mecanismos para detectar alteração, perda ou repetição de dados. O TLS também incorpora algoritmos que fornecem verificação de identidade usando o padrão X.509. SSL ou TLS está sendo usado de forma intercambiável, mas para o contexto de criptografia com MySQL, TLS está sendo usado para o qual MySQL suporta conexões criptografadas usando os protocolos TLSv1, TLSv1.1, TLSv1.2 e TLSv1.3.
X.509 torna possível identificar alguém na Internet. Em termos básicos, deve haver alguma entidade chamada “Autoridade Certificadora” (ou CA) que atribui certificados eletrônicos a qualquer pessoa que precise deles. Os certificados contam com algoritmos de criptografia assimétrica que possuem duas chaves de criptografia (uma chave pública e uma chave secreta). Um proprietário de certificado pode apresentar o certificado a outra parte como prova de identidade. Um certificado consiste na chave pública de seu proprietário. Quaisquer dados criptografados usando essa chave pública podem ser descriptografados apenas usando a chave secreta correspondente, que é mantida pelo proprietário do certificado.
Assim como os espartanos usavam Scytale
Scytale é conhecido por ser usado como uma maneira de criptografar e descriptografar uma mensagem que foi usada por volta de 400 a.C. pelos espartanos. Eles escreviam uma mensagem em uma folha de papiro (um tipo de papel) que era enrolada em um cajado. O destinatário só pode decifrar a mensagem se o diâmetro e o tamanho corretos da pauta. Ele serve como uma maneira de criptografar e evitar a extração não autorizada de mensagens ou dados para o destino de destino.
Assim como no MySQL, usar protocolos e cifras SSL/TLS é uma maneira de evitar que alguém extraia seus dados ou sequestre seus dados enquanto eles passam pela rede ou pela Internet.
Por padrão, os programas MySQL tentam se conectar usando criptografia se o servidor suportar conexões criptografadas, voltando para uma conexão não criptografada se uma conexão criptografada não puder ser estabelecida. Desde a versão MySQL>=5.7, arquivos TLS/SSL e RSA podem ser criados ou gerados com o suporte de variáveis. Para distribuições MySQL compiladas usando OpenSSL, o servidor MySQL tem a capacidade de gerar automaticamente arquivos SSL e RSA ausentes na inicialização. As variáveis auto_generate_certs, sha256_password_auto_generate_rsa_keys e caching_sha2_password_auto_generate_rsa_keys (versão>=8.0), controlam a geração automática desses arquivos. Essas variáveis são habilitadas por padrão. Eles podem ser ativados na inicialização e inspecionados, mas não definidos em tempo de execução.
Por padrão, essas variáveis são definidas como LIGADAS ou habilitadas. Caso contrário, os usuários podem invocar o utilitário mysql_ssl_rsa_setup manualmente. Para alguns tipos de distribuição, como pacotes RPM e DEB, a chamada mysql_ssl_rsa_setup ocorre durante a inicialização do diretório de dados. Neste caso, a distribuição MySQL não precisa ter sido compilada usando OpenSSL desde que o comando openssl esteja disponível.
Uma vez que esses arquivos estejam disponíveis e/ou gerados, o MySQL ainda não usará conexões de criptografia pelos seguintes motivos. Como mencionado anteriormente, por padrão, os programas cliente MySQL tentam estabelecer uma conexão criptografada se o servidor suportar conexões criptografadas, com controle adicional disponível através do --ssl-mode (ou --ssl <=5.7.11, pois isso já está obsoleto) opção:
-
Por padrão, se a conexão MySQL não estiver sinalizada com --ssl-mode, o valor padrão será definido como --ssl-mode=PREFERIDO. Portanto, os clientes tentam se conectar usando criptografia, voltando para uma conexão não criptografada se uma conexão criptografada não puder ser estabelecida.
-
Com --ssl-mode=REQUIRED, os clientes exigem uma conexão criptografada e falham se não for possível estabelecer uma.
-
Com --ssl-mode=DISABLED, os clientes usam uma conexão não criptografada.
-
Com --ssl-mode=VERIFY_CA ou --ssl-mode=VERIFY_IDENTITY, os clientes exigem uma conexão criptografada e também realizar a verificação no certificado CA do servidor e (com VERIFY_IDENTITY) no nome do host do servidor em seu certificado.
Com o mecanismo padrão do MySQL para usar uma conexão preferencial, provavelmente ele tenta tentar usar a conexão criptografada ou segura, mas isso ainda deixa algumas coisas para fazer e determinar.
Como mencionado anteriormente, as variáveis auto_generate_certs, sha256_password_auto_generate_rsa_keys e caching_sha2_password_auto_generate_rsa_keys (versão>=8.0) ajudam a gerar os arquivos SSL/TLS e RSA necessários, com o usuário normal sem tais requisitos durante a conexão ainda deve ser inseguro. Por exemplo, vamos criar um usuário chamado dbadmin.
mysql> create user 'dbadmin'@'192.168.40.%' identified by '[email protected]';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'192.168.40.%';
Query OK, 0 rows affected (0.01 sec)
Em seguida, verifique se as variáveis estão configuradas corretamente, que devem ser habilitadas como estão por padrão:
mysql> show global variables where variable_name in ('auto_generate_certs','sha256_password_auto_generate_rsa_keys','caching_sha2_password_auto_generate_rsa_keys');
+----------------------------------------------+-------+
| Variable_name | Value |
+----------------------------------------------+-------+
| auto_generate_certs | ON |
| caching_sha2_password_auto_generate_rsa_keys | ON |
| sha256_password_auto_generate_rsa_keys | ON |
+----------------------------------------------+-------+
3 rows in set (0.00 sec)
Verificando se os arquivos são gerados de acordo no caminho /var/lib/mysql/ (ou o caminho do datadir para este MySQL):
$ find /var/lib/mysql -name "*.pem"
/var/lib/mysql/ca-key.pem
/var/lib/mysql/ca.pem
/var/lib/mysql/server-key.pem
/var/lib/mysql/server-cert.pem
/var/lib/mysql/client-key.pem
/var/lib/mysql/client-cert.pem
/var/lib/mysql/private_key.pem
/var/lib/mysql/public_key.pem
Em seguida, verifique se os arquivos SSL foram carregados corretamente:
mysql> show global variables like 'ssl%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| ssl_ca | ca.pem |
| ssl_capath | |
| ssl_cert | server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_fips_mode | OFF |
| ssl_key | server-key.pem |
+---------------+-----------------+
8 rows in set (0.00 sec)
Determine a segurança da sua conexão
Agora, isso parece bom. Isso também significa que o MySQL está pronto para aceitar conexões criptografadas. Mas conectar-se ao MySQL como está, conforme declarado, deve usar --ssl-mode=PREFFERED por padrão, ou se --ssl-mode não for especificado, ele ainda fará o failback para usar uma conexão não criptografada. Ver abaixo:
$ mysql [email protected] -h 192.168.40.110 -udbadmin -e "status;"|grep ssl -i
SSL: Não está em uso
Isso revela que não está usando uma conexão segura. A verificação das variáveis de status da sessão SSL se alguma cifra for usada revela vazio:
mysql> show global status like 'ssl%';
+--------------------------------+--------------------------+
| Variable_name | Value |
+--------------------------------+--------------------------+
| Ssl_accept_renegotiates | 0 |
| Ssl_accepts | 2 |
| Ssl_callback_cache_hits | 0 |
| Ssl_cipher | |
| Ssl_cipher_list | |
| Ssl_client_connects | 0 |
| Ssl_connect_renegotiates | 0 |
| Ssl_ctx_verify_depth | 18446744073709551615 |
| Ssl_ctx_verify_mode | 5 |
| Ssl_default_timeout | 0 |
| Ssl_finished_accepts | 2 |
| Ssl_finished_connects | 0 |
| Ssl_server_not_after | Aug 28 12:48:46 2031 GMT |
| Ssl_server_not_before | Aug 30 12:48:46 2021 GMT |
| Ssl_session_cache_hits | 0 |
| Ssl_session_cache_misses | 0 |
| Ssl_session_cache_mode | SERVER |
| Ssl_session_cache_overflows | 0 |
| Ssl_session_cache_size | 128 |
| Ssl_session_cache_timeouts | 0 |
| Ssl_sessions_reused | 0 |
| Ssl_used_session_cache_entries | 0 |
| Ssl_verify_depth | 0 |
| Ssl_verify_mode | 0 |
| Ssl_version | |
+--------------------------------+--------------------------+
25 rows in set (0.002 sec)
Como aplicar uma conexão segura
Uma vez que revela que a conexão ainda não está segura, o MySQL introduz a variável require_secure_transport que requer que todas as conexões sejam criptografadas e protegidas. Todas as tentativas de conexão para uma conexão não segura falham. Por exemplo, habilitando-o no servidor:
mysql> set global require_secure_transport=1;
Query OK, 0 rows affected (0.00 sec)
Tentar se conectar como cliente usando uma conexão não criptografada falhará:
$ mysql [email protected] -h 192.168.40.110 -udbadmin
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.
Para conectar com sucesso e segurança, você precisa especificar as variáveis ssl-ca, ssl-cert, ssl-key. Ver abaixo:
$ mysql [email protected] -h 192.168.40.110 -udbadmin --ssl-ca=/tmp/pem/ca.pem --ssl-cert=/tmp/pem/server-cert.pem --ssl-key=/tmp/pem/server-key.pem -e "show global status like 'ssl%'\G"
*************************** 1. row ***************************
Variable_name: Ssl_accept_renegotiates
Value: 0
*************************** 2. row ***************************
Variable_name: Ssl_accepts
Value: 16
*************************** 3. row ***************************
Variable_name: Ssl_callback_cache_hits
Value: 0
*************************** 4. row ***************************
Variable_name: Ssl_cipher
Value: TLS_AES_256_GCM_SHA384
*************************** 5. row ***************************
Variable_name: Ssl_cipher_list
Value: TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:CAMELLIA128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA
*************************** 6. row ***************************
Variable_name: Ssl_client_connects
Value: 0
*************************** 7. row ***************************
Variable_name: Ssl_connect_renegotiates
Value: 0
*************************** 8. row ***************************
Variable_name: Ssl_ctx_verify_depth
Value: 18446744073709551615
*************************** 9. row ***************************
Variable_name: Ssl_ctx_verify_mode
Value: 5
*************************** 10. row ***************************
Variable_name: Ssl_default_timeout
Value: 7200
*************************** 11. row ***************************
Variable_name: Ssl_finished_accepts
Value: 11
*************************** 12. row ***************************
Variable_name: Ssl_finished_connects
Value: 0
*************************** 13. row ***************************
Variable_name: Ssl_server_not_after
Value: Aug 28 12:48:46 2031 GMT
*************************** 14. row ***************************
Variable_name: Ssl_server_not_before
Value: Aug 30 12:48:46 2021 GMT
*************************** 15. row ***************************
Variable_name: Ssl_session_cache_hits
Value: 0
*************************** 16. row ***************************
Variable_name: Ssl_session_cache_misses
Value: 0
*************************** 17. row ***************************
Variable_name: Ssl_session_cache_mode
Value: SERVER
*************************** 18. row ***************************
Variable_name: Ssl_session_cache_overflows
Value: 0
*************************** 19. row ***************************
Variable_name: Ssl_session_cache_size
Value: 128
*************************** 20. row ***************************
Variable_name: Ssl_session_cache_timeouts
Value: 0
*************************** 21. row ***************************
Variable_name: Ssl_sessions_reused
Value: 0
*************************** 22. row ***************************
Variable_name: Ssl_used_session_cache_entries
Value: 0
*************************** 23. row ***************************
Variable_name: Ssl_verify_depth
Value: 18446744073709551615
*************************** 24. row ***************************
Variable_name: Ssl_verify_mode
Value: 5
*************************** 25. row ***************************
Variable_name: Ssl_version
Value: TLSv1.3
Como alternativa, se um usuário for criado com SSL REQUIRED, por exemplo, isso também deve conectá-lo usando SSL, independentemente de require_secure_transport estar desabilitado, que é seu valor padrão. Observe que, se require_secure_transport estiver ativado, seu recurso complementa os requisitos de SSL por conta, que têm precedência. Portanto, se uma conta for definida com REQUIRE SSL, habilitar require_secure_transport não possibilitará usar a conta para conectar usando um arquivo de soquete Unix.
Garantindo que as implantações do servidor MySQL sejam criptografadas e seguras
Sem complicações é o que sempre esperamos para que não haja outros problemas e preocupações com que se preocupar. O ClusterControl implanta bancos de dados MySQL usando conexões criptografadas e gera os certificados SSL e RSA para você. Por exemplo, uma captura de tela abaixo mostrando a atividade de trabalho de um comando Criar cluster do ClusterControl.
Ele configura os arquivos SSL e RSA e os coloca em /etc/ mysql/certs/ caminho como abaixo:
mysql> show global variables like 'ssl%';
+---------------+--------------------------------+
| Variable_name | Value |
+---------------+--------------------------------+
| ssl_ca | /etc/mysql/certs/server_ca.crt |
| ssl_capath | |
| ssl_cert | /etc/mysql/certs/server.crt |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /etc/mysql/certs/server.key |
+---------------+--------------------------------+
7 rows in set (0.00 sec)
O ClusterControl também agrupa os arquivos SSL e RSA gerados de forma centralizada no painel de navegação Key Management, conforme mostrado abaixo:
Uma vez implantado, tudo o que você precisa fazer é criar usuários com SSL REQUIRED ou ter require_secure_transport se quiser impor uma camada criptografada e segura para suas conexões de servidor MySQL.