Conexões Criptografadas

Quando iniciamos uma conexão com o MySQL, geralmente, alguém com acesso ao tráfego da rede poderia espionar toda a conexão e os dados sendo enviados e recebidos por nós e servidor. O ideal é que o servidor do MySQL não fique exposto na internet, mas mesmo que não esteja, essa espionagem pode acontecer na rede interna. O MySQL suporta conexões criptografadas através de TLS - Transport Security Layer, muitas vezes conhecido pelo seu antecessor SSL - verificando as identidades através de certificados X509.

O fluxo da criação de um certificado funciona da seguinte forma:

  1. Os clientes com suas chaves privadas criam um CSR e enviam para a CA.
  2. A CA então utiliza o CSR para criar um certificado para o cliente.
  3. O cliente utiliza este certificado para se conectar ao servidor.

Por padrão o client do MySQL tenta primeiro se conectar através de uma conexão segura, só então, se não obter sucesso, ele passa a utilizar uma conexão comum. A utilização de uma conexão criptografada para um determinado usuário pode ser opcional ou obrigatória.

Conexões seguras também podem ser utilizadas em replicações Master e Slave.

Por padrão, nas distribuições mais comuns, o MySQL já está configurado para receber conexões seguras:

SHOW VARIABLES LIKE '%ssl_%';

O retorno deverá mostrar o certificado da CA, o certificado e a chave do servidor MySQL, semelhante ao seguinte:

+--------------------------+-----------------+
| Variable_name            | Value           |
+--------------------------+-----------------+
| ssl_ca                   | ca.pem          |
| ssl_capath               |                 |
| ssl_cert                 | server-cert.pem |
| ssl_cipher               |                 |
| ssl_crl                  |                 |
| ssl_crlpath              |                 |
| ssl_key                  | server-key.pem  |
+--------------------------+-----------------+

Verique que a conexão já está - e provavelmente sempre esteve - segura com o comando \s, atente-se ao SSL:

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.27, for Linux (x86_64) using  EditLine wrapper

Connection id:          18
Current database:
Current user:           hector@hectorvido.dev
SSL:                    Cipher in use is DHE-RSA-AES256-SHA
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.27 MySQL Community Server (GPL)
Protocol version:       10
Connection:             35.237.254.148 via TCP/IP
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
TCP port:               3306
Uptime:                 9 min 22 sec

Threads: 1  Questions: 29  Slow queries: 0  Opens: 105  Flush tables: 1  Open tables: 98  Queries per second avg: 0.051
--------------

Utilização de certificado

Existem uma série de verificações em relação aos certificados, mas vou focar apenas em um dos pontos mais básicos, criar um usuário que não se conecta através de senha, mas sim, através de um certificado de identidade:

CREATE USER criptografo@"%" REQUIRE X509;
GRANT ALL ON *.* TO criptografo@'%';

As opções de conexões através do client podem ser vistas com o seguinte comando:

mysql --help | grep -- --ssl

Obs: Os dois traços no Linux indicam que nenhum parâmetro de configuração será enviado para o binário utilizado.

A única forma deste usuário acessar o banco de dados é especificando uma chave juntamente com o certificado assinado pelo servidor MySQL - e opcionalmente o certificado da CA. Você pode copiar os arquivos client-cert.pem e client-key.pem que o MySQL criou em /var/lib/mysql para outro computador e testar a conexão:

mysql -u criptografo --ssl-key='/var/lib/mysql/client-key.pem' --ssl-cert='/var/lib/mysql/client-cert.pem'