Na postagem anterior sobre segurança do MySQL, abordamos uma variedade de opções que podem ser usadas para tornar suas instâncias do MySQL mais seguras. Eles incluíram:
- Medidas gerais de segurança do MySQL;
- Controlando o acesso no MySQL;
- Criando, alterando e excluindo usuários no MySQL;
- Conceder e revogar privilégios para e de usuários no MySQL;
- Verificando quais privilégios são atribuídos aos usuários no MySQL.
Neste post, vamos mergulhar no restante das opções, incluindo:
- Categorias de conta no MySQL;
- Funções no MySQL;
- Contas reservadas no MySQL;
- Gerenciamento de senhas no MySQL;
- Bloqueio de conta no MySQL;
- Plugins de segurança oferecidos pelo MySQL;
- Protegendo backups do MySQL.
Lembre-se de que, mais uma vez, não abordaremos absolutamente tudo o que você precisa saber, mas tentaremos fornecer bons pontos de partida para fazer sua própria pesquisa.
Categorias de conta no MySQL
As categorias de conta foram introduzidas no MySQL 8 - especificamente, no MySQL 8.0.16. Aqui está o cerne disso:
- Existem duas categorias de contas separadas:usuários regulares e usuários do sistema;
- Um usuário normal é um usuário sem o privilégio SYSTEM_USER - um usuário do sistema é um usuário com o privilégio SYSTEM_USER;
- Um usuário comum pode modificar contas comuns - esse usuário não pode modificar contas do sistema;
- Um usuário do sistema pode modificar contas do sistema e contas normais;
- As contas normais podem ser modificadas por usuários comuns e usuários do sistema;
- As contas do sistema só podem ser modificadas pelos usuários do sistema.
Para fazer uso de categorias de contas no MySQL em termos de segurança, lembre-se de que o privilégio SYSTEM_USER afeta coisas como manipulação de contas e matando sessões e instruções dentro delas - este conceito no MySQL permite restringir certas modificações para certas contas tornando o MySQL mais seguro. As categorias de conta também podem ser usadas para proteger contas do sistema contra manipulação por contas regulares:para isso, não conceda privilégios de modificação de esquema mysql para contas regulares.
Para conceder privilégios SYSTEM_USER a uma conta, use a seguinte consulta em uma conta criada:
GRANT SYSTEM_USER ON *.* TO system_user;
Funções no MySQL
No MySQL, os papéis são coleções de privilégios. Ao conceder uma função a uma conta de usuário no MySQL, você concede todos os privilégios associados a essa função. As funções podem ser criadas usando a instrução CREATE ROLE:
CREATE ROLE ‘role_1’, ‘role_2’;
Os nomes de funções consistem em uma parte do usuário e uma parte do host - a parte do usuário não pode ficar em branco e a parte do host tem como padrão “%” se não for especificada.
Quando as funções são criadas, você deve atribuir privilégios a elas. Privilégios podem ser atribuídos usando a instrução GRANT:
- GRANT ALL ON demo_database.* TO 'demo_user'; concederia todos os privilégios a um usuário chamado demo_user em um banco de dados chamado demo_database;
- GRANT INSERT, SELECT, UPDATE, DELETE ON database.* TO 'demo_user'; concederia privilégios INSERT, SELECT, UPDATE e DELETE a um usuário chamado demo_user em um banco de dados chamado demo_database;
- GRANT SELECT ON demo_database.* TO 'demo_user'; concederia privilégios SELECT a um usuário chamado demo_user em um banco de dados chamado demo_database.
Para atribuir uma função a um usuário individual, use esta sintaxe:
GRANT ‘role_name’ TO ‘user_name’@’localhost’;
Para atribuir várias funções a um usuário individual, use esta sintaxe:
GRANT ‘role_1’, ‘role_2’ TO ‘user_name’@’localhost’;
Para atribuir funções a vários usuários ao mesmo tempo, use esta sintaxe:
GRANT ‘role_name’ TO ‘user1’@’localhost’, ‘user2’@’localhost’;
As funções podem ser úteis na prevenção de incidentes de segurança porque, se um invasor souber a senha de um usuário não muito privilegiado, presumindo erroneamente que o usuário é muito “poderoso” em termos de função, seu aplicativo (e seu banco de dados) poderá fique muito bem guardado.
Contas reservadas no MySQL
Quando se trata de contas reservadas, tenha em mente que o MySQL cria contas durante a inicialização do diretório de dados. Existem algumas contas que devem ser consideradas reservadas no MySQL:
- ‘root’@’localhost’ - esta conta é uma conta de superusuário e tem privilégios divinos em todos os bancos de dados MySQL (pode executar qualquer operação em qualquer banco de dados MySQL). Vale a pena notar que o usuário root também pode ser renomeado para evitar a exposição de uma conta altamente privilegiada. Para renomear a conta, execute a seguinte consulta:
RENAME USER ‘root’@’localhost’ TO ‘username’@’localhost’;
- Certifique-se de emitir um FLUSH PRIVILEGES; após renomear a conta para que as alterações entrem em vigor.
- ‘mysql.sys’@’localhost’ - esta conta é um usuário do sistema que é usado como definidor para visualização, procedimentos e funções no esquema sys. Adicionado no MySQL 5.7.9 para evitar problemas que possam surgir se a conta root for renomeada.
- ‘mysql.session’@’localhost’ - esta conta é usada internamente por plugins para acessar o servidor.
Neste caso, você não pode fazer muito em termos de segurança, mas tenha em mente que a conta root tem privilégios divinos, o que significa que ela pode executar qualquer operação em qualquer banco de dados MySQL e tenha cuidado ao decidir a quem conceder os privilégios de acesso à conta. Além disso, tenha em mente para que as outras contas MySQL são usadas.
Gerenciamento de senhas no MySQL
O MySQL também suporta recursos de gerenciamento de senha. Alguns deles incluem:
- A capacidade de expirar senhas periodicamente;
- A capacidade de evitar a reutilização de senhas;
- A capacidade de gerar senhas;
- A capacidade de verificar se a senha em uso é forte;
- A capacidade de bloquear temporariamente os usuários após muitas tentativas de login com falha.
Agora, examinaremos essas opções mais detalhadamente.
Para expirar uma senha manualmente, use a instrução ALTER USER da seguinte forma:
ALTER USER ‘user’@’localhost’ PASSWORD EXPIRE;
Para definir uma política global, modifique o arquivo my.cnf de forma que inclua o parâmetro default_password_lifetime. O parâmetro pode ser definido abaixo da seção [mysqld] (o exemplo a seguir define a vida útil da senha para 3 meses (90 dias)):
default_password_lifetime=90
Se você quiser que as senhas nunca expirem, defina o parâmetro default_password_litetime como 0.
Você também pode definir a expiração da senha para usuários específicos. Se você quiser definir o intervalo de expiração de senha para um usuário chamado demo_user, poderá usar o seguinte exemplo:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE INTERVAL 90 DAY;
Para desabilitar a expiração da senha:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE NEVER;
Para redefinir a política global de expiração de senha:
ALTER USER ‘demo_user’@’localhost’ PASSWORD EXPIRE DEFAULT;
Restrições de reutilização de senha não permitem que senhas sejam reutilizadas - para fazer uso desse recurso, use as variáveis password_history e password_reuse_interval. Você pode colocar essas variáveis em my.cnf observando o exemplo abaixo ou defini-las em tempo de execução adicionando SET PERSIST na frente das instruções abaixo.
Para proibir a reutilização de qualquer uma das 5 senhas usadas anteriormente com mais de 365 dias, use:
password_history=5
password_reuse_interval=365
Para exigir no mínimo 5 alterações de senha antes de permitir a reutilização:
ALTER USER ‘demo_user’@’localhost’ PASSWORD HISTORY 5;
O mesmo pode ser feito ao criar um usuário - substitua ALTER USER por CREATE USER.
Para gerar uma senha aleatória ao criar um usuário, execute:
CREATE USER [email protected] IDENTIFIED BY RANDOM PASSWORD;
Para alterar a senha de um usuário para uma gerada aleatoriamente:
SET PASSWORD FOR [email protected] TO RANDOM;
Sua senha aleatória será exibida abaixo.
Lembre-se de que as senhas aleatórias padrão têm um comprimento de 20 caracteres. O comprimento pode ser controlado pela variável generate_random_password_length que tem um intervalo de 5 a 255.
Para verificar se uma senha usada é forte, você pode usar a variável VALIDATE_PASSWORD_STRENGTH - a função exibe um número de 0 a 100 sendo 0 o mais fraco e 100 o mais forte:
SELECT VALIDATE_PASSWORD_STRENGTH('senha');
Bloqueio de conta no MySQL
O MySQL 8.0.19 também introduziu a capacidade de bloquear temporariamente contas de usuários. Isso pode ser feito usando as variáveis FAILED_LOGIN_ATTEMPTS e PASSWORD_LOCK_TIME.
Para habilitar o bloqueio de conta ao criar um usuário, execute:
CREATE USER ‘demo_user’@’localhost’ IDENTIFIED BY ‘password’ FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 5;
O valor após FAILED_LOGIN_ATTEMPTS especifica após quantas tentativas com falha a conta é bloqueada, o valor após PASSWORD_LOCK_TIME especifica o tempo de bloqueio da conta em dias. Também é possível especificar um valor que não termina até que a conta seja desbloqueada especificando PASSWORD_LOCK_TIME como UNBOUNDED.
Plugins de segurança oferecidos pelo MySQL
O MySQL também oferece alguns plugins que podem aprimorar ainda mais os recursos de segurança. MySQL oferece:
- Plugins de autenticação;
- Plugins de controle de conexão;
- Plugins de validação de senha;
- Plugins de auditoria;
- Plugins de firewall;
Esses plugins podem ser usados para várias coisas em termos de segurança:
Plugins de autenticação
Os plug-ins de autenticação podem permitir que os usuários escolham entre vários métodos de autenticação conectáveis disponíveis no MySQL. Eles podem ser usados em conjunto com as instruções CREATE USER ou ALTER USER. Aqui está um exemplo:
CREATE USER ‘user_1’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘password’;
Esta consulta implementaria a autenticação usando o método de hash de senha nativo.
Plugins de controle de conexão
Os plug-ins de controle de conexão podem apresentar um atraso crescente nas respostas do servidor às tentativas de conexão se as tentativas de conexão excederem um determinado número - eles são capazes de interromper possíveis ataques de força bruta. Esta biblioteca de plugins foi introduzida no MySQL na versão 5.7.17 e pode ser adicionada ao MySQL via my.cnf ou carregando os plugins no servidor em tempo de execução.
Para adicionar os plugins ao my.cnf , adicione a seguinte linha abaixo de [mysqld]:
plugin-load-add=connection_control.so
Após modificar o arquivo, salve suas alterações e reinicie o MySQL.
Para carregar os plugins no servidor em tempo de execução, execute:
INSTALL PLUGIN CONNECTION_CONTROL SONAME ‘connection_control.so’;
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME ‘connection_control.so’;
Ajuste o sufixo .so conforme necessário. Se você fez tudo corretamente, a tabela CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS deve conter todas as tentativas malsucedidas de conexão.
Plugins de validação de senha
Os plug-ins de validação de senha podem permitir que os usuários usem senhas mais fortes se usados corretamente. O plugin de validação de senha pode ser instalado via my.cnf ou carregando o plugin no servidor em tempo de execução. Para instalar o plugin via my.cnf, adicione a seguinte linha abaixo de [mysqld] e reinicie o servidor:
plugin-load-add=validate_password.so
Para carregar o plug-in em tempo de execução, execute a seguinte instrução:
INSTALL PLUGIN validate_password SONAME ‘validate_password.so’;
Para carregar o plug-in em tempo de execução e evitar que ele seja removido, adicione validate-password=FORCE_PLUS_PERMANENT ao my.cnf.
Para evitar que o servidor seja executado se o plug-in não for inicializado, use a opção --validate-password com um valor FORCE ou FORCE_PLUS_PERMANENT.
A política de segurança da senha também pode ser alterada:para isso, altere o valor validate_password_policy para LOW, MEDIUM ou STRONG. O valor de LOW verifica apenas o comprimento da senha, a política MEDIUM adiciona algumas condições e a política STRONG adiciona a condição de que substrings de senha que consistem em 4 ou mais caracteres não devem corresponder a palavras em um arquivo de dicionário que pode ser especificado modificando a variável validate_password_dictionary_file.
Plugins de chaveiro
Os plug-ins de chaveiro podem permitir que os componentes e plug-ins do servidor armazenem com segurança informações confidenciais para recuperação. Para carregar o plugin no MySQL, adicione o seguinte abaixo de [mysqld]:
early-plugin-load=keyring_file.so
Para especificar o arquivo do cofre do chaveiro, adicione o seguinte (a variável keyring_vault_config deve apontar para o arquivo de configuração):
loose-keyring_vault_config=”/var/lib/mysql_keyring/keyring_vault.conf”
O arquivo de chaveiro deve conter a variável vault_url que define o endereço do servidor do cofre, a variável secret_mount_point que define o nome do ponto de montagem onde o cofre do chaveiro armazena as chaves e um token que deve ser definido pelo servidor do vault. Opcionalmente, a variável vault_ca também pode ser definida (deve apontar para o certificado CA usado para assinar os certificados do vault).
Reinicie o servidor para que as alterações tenham efeito;
Plugins de auditoria
Os plug-ins de auditoria podem permitir o monitoramento, registro e bloqueio de atividades realizadas em servidores MySQL. Para instalar o MySQL Enterprise Audit, execute um script localizado no diretório de compartilhamento de sua instância MySQL (evite colocar a senha da instância MySQL no terminal - use my.cnf):
mysql < /path/to/audit_log_filter_linux_install.sql
Você também pode impedir que o plugin seja removido em tempo de execução - adicione o seguinte na seção [mysqld]:
audit_log=FORCE_PLUS_PERMANENT
Reinicie o servidor para aplicar as alterações. Observe que o registro baseado em regras não registra eventos auditáveis por padrão, portanto, para que ele registre tudo, crie um filtro:
SELECT audit_log_filter_set_filter(‘log_filter’, ‘{ “filter”: { “log”: true } }’);
Em seguida, atribua-o a uma conta:
SELECT audit_log_filter_set_user(‘%’, ‘log_filter’);
Observe que os plug-ins de auditoria estão disponíveis apenas no MySQL Enterprise Edition;
Plugins de firewall
Os plug-ins de firewall podem permitir que os usuários permitam ou neguem a execução de instruções SQL específicas com base em padrões específicos. O MySQL Enterprise Firewall foi introduzido no MySQL 5.6.24 - é capaz de proteger dados monitorando, alertando e bloqueando atividades não autorizadas:é capaz de bloquear ataques de injeção de SQL, monitorar ameaças e bloquear tráfego suspeito, bem como detectar intrusões em o banco de dados. O firewall também é capaz de registrar declarações bloqueadas - elas podem ser inspecionadas e uma contagem em tempo real de declarações aprovadas e rejeitadas também pode ser observada.
Para instalar o MySQL Enterprise Firewall, basta habilitá-lo ao instalar o MySQL Server no Windows, ele também pode ser instalado, desabilitado ou desinstalado com a ajuda do MySQL Workbench 6.3.4. O firewall também pode ser instalado manualmente executando um script no diretório de compartilhamento de sua instalação do MySQL. Para habilitar o firewall, adicione a seguinte linha abaixo de [mysqld] e reinicie o servidor:
mysql_firewall_mode=ON
O firewall também pode ser habilitado em tempo de execução:
SET GLOBAL mysql_firewall_mode = ON;
Como alternativa, para persistir o firewall (o que significa que o firewall não precisará ser reativado em cada reinicialização subsequente do servidor):
SET PERSIST mysql_firewall_mode = ON;
Em seguida, conceda um privilégio FIREWALL_ADMIN a qualquer conta que administre o firewall e o privilégio FIREWALL_USER a qualquer conta que deva ter acesso apenas às suas próprias regras de firewall. Além disso, conceda o privilégio EXECUTE para os procedimentos armazenados do firewall no banco de dados mysql. Para que o firewall funcione, registre os perfis nele, então treine o firewall para conhecer as instruções permitidas que o banco de dados pode executar e depois diga ao firewall para comparar as instruções recebidas com a lista branca definida. Cada perfil tem um modo operacional - OFF, RECORDING, PROTECTING ou DETECTING. OFF desabilita o perfil, RECORDING treina o firewall, PROTECTING permite ou nega a execução de instruções e DETECTING detecta (mas não bloqueia) tentativas de intrusão. As regras para um perfil especificado podem ser redefinidas definindo seu valor como RESET. OFF irá desabilitar o perfil. Para definir o modo, use a seguinte consulta onde name é o nome do perfil e OFF é o modo operacional:
CALL mysql.sp_set_firewall_mode(name, ‘OFF’);
O plug-in de firewall também está disponível apenas no MySQL Enterprise Edition.
Protegendo backups do MySQL
No que diz respeito aos backups do MySQL, você tem algumas opções.
- Se você estiver usando mysqldump, você pode armazenar seu nome de usuário e senha em my.cnf e invocar mysqldump assim (o comando a seguir irá despejar todos os bancos de dados em um arquivo /home/backup.sql):
$ mysqldump --defaults-extra-file=/var/lib/my.cnf --single-transaction --all-databases > /home/backup.sql
- Ao armazenar seu nome de usuário e senha dentro de my.cnf, você não escreve sua senha dentro do terminal - esse método para fazer backups é mais seguro porque enquanto o dump está em execução o comando pode ser visto através do ps ax comando.
-
Você também pode considerar usar mysqldump-secure que é um script wrapper compatível com POSIX que é capaz de compactar e criptografar backups com forte segurança em mente .
-
Os backups podem ser criptografados usando OpenSSL - basta fazer o backup e criptografá-lo com o seguinte comando:
$ openssl enc -aes-256-cbc -salt -in backup.tar.gz -out backup.tar.gz.enc -k password
O comando acima criará um novo arquivo criptografado backup.tar.gz.enc no diretório atual. O arquivo será criptografado com a senha que você escolheu (substitua a senha pela senha desejada). O arquivo pode ser descriptografado posteriormente executando o seguinte comando:
$ openssl aes-256-cbc -d -in backup.tar.gz.enc -out backup.tar.gz -k password
Substitua a senha pela sua senha.
-
mysqldump tem outra opção para criptografar seus backups (o exemplo a seguir também os compacta com gzip):
$ mysqldump --all-databases --single-transaction --triggers --routines | gzip | openssl enc -aes-256-cbc -k password > backup.xb.enc
Substitua a senha pela senha desejada.
-
Você também pode criptografar seus backups usando mariabackup ou xtrabackup. Aqui está um exemplo da documentação do MariaDB:
$ mariabackup --user=root --backup --stream=xbstream | openssl enc -aes-256-cbc -k password > backup.xb.enc
Substitua a senha pela senha desejada.
-
Os backups também podem ser criptografados usando ClusterControl - se a opção de criptografia estiver habilitada para um backup específico, o ClusterControl criptografará o backup usando AES-256 CBC (a criptografia acontece no nó de backup). Se o backup for armazenado em um nó do controlador, os arquivos de backup serão transmitidos em um formato criptografado usando socat ou netcat. Se a compactação estiver habilitada, o ClusterControl primeiro compactará o backup, depois disso - o criptografará. A chave de criptografia será gerada automaticamente se não existir, então armazenada dentro da configuração CMON na opção backup_encryption_key. Tenha em mente que esta chave é codificada e deve ser decodificada primeiro. Para isso, execute o seguinte comando:
$ cat /etc/cmon.d/cmon_ClusterID.cnf | grep ^backup_encryption_key | cut -d"'" -f2 | base64 -d > keyfile.key
O comando lerá o backup_encryption_key e decodificará seu valor em uma saída binária. O keyfile pode ser usado para descriptografar o backup da seguinte forma:
$ cat backup.aes256 | openssl enc -d -aes-256-cbc -pass file:/path/to/keyfile.key > backup_file.xbstream.gz
Para obter mais exemplos, consulte a documentação do ClusterControl.
Conclusão
Nestas postagens sobre segurança do MySQL, abordamos algumas medidas de segurança que podem ser úteis se você sentir a necessidade de aumentar a segurança de sua(s) instância(s) do MySQL. Embora não tenhamos coberto absolutamente tudo, sentimos que esses pontos podem ser um bom ponto de partida para aumentar a segurança de sua instalação do MySQL. Tire dessas postagens o que você quiser, faça sua própria pesquisa e aplique as medidas de segurança mais aplicáveis à sua situação.