Como um sistema de banco de dados distribuído, o Galera Cluster requer medidas de segurança adicionais em comparação com um banco de dados centralizado. Os dados são distribuídos por vários servidores ou até mesmo datacenters. Com a comunicação de dados significativa ocorrendo entre os nós, pode haver uma exposição significativa se as medidas de segurança apropriadas não forem tomadas.
Neste post do blog, veremos algumas dicas sobre como proteger nosso Galera Cluster. Observe que este blog se baseia em nossa postagem anterior - Como proteger seus bancos de dados de código aberto com o ClusterControl.
Grupo de firewall e segurança
As seguintes portas são muito importantes para um Galera Cluster:
- 3306 - MySQL
- 4567 - Comunicação e replicação Galera
- 4568 - Galera IST
- 4444 - Galera SST
A partir da rede externa, recomenda-se abrir apenas o acesso à porta 3306 do MySQL. As outras três portas podem ser fechadas a partir da rede externa, permitindo apenas acesso interno entre os nós Galera. Se você estiver executando um proxy reverso na frente dos nós Galera, por exemplo HAProxy, você pode bloquear a porta MySQL do acesso público. Certifique-se também de que a porta de monitoramento para o script de monitoramento HAProxy esteja aberta. A porta padrão é 9200 no nó Galera.
O diagrama a seguir ilustra nossa configuração de exemplo em um Galera Cluster de três nós, com um HAProxy voltado para a rede pública com suas portas relacionadas:
Com base no diagrama acima, os comandos iptables para nós de banco de dados são:
$ iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 3306 -j ACCEPT
$ iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 4444 -j ACCEPT
$ iptables -A INPUT -p tcp -s 10.0.0.0/24 --dports 4567:4568 -j ACCEPT
$ iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 9200 -j ACCEPT
Enquanto estiver no balanceador de carga:
$ iptables -A INPUT -p tcp --dport 3307 -j ACCEPT
Certifique-se de encerrar suas regras de firewall com negar tudo, para que apenas o tráfego conforme definido nas regras de exceção seja permitido. Você pode ser mais rigoroso e estender os comandos para seguir sua política de segurança - por exemplo, adicionando interface de rede, endereço de destino, endereço de origem, estado de conexão e outros.
Criptografia cliente-servidor MySQL
MySQL suporta criptografia entre o cliente e o servidor. Primeiro temos que gerar o certificado. Uma vez configurado, você pode impor contas de usuário para especificar certas opções para conectar com criptografia a um servidor MySQL.
As etapas exigem que você:
- Crie uma chave para a Autoridade de Certificação (ca-key.pem)
- Gere um certificado de CA autoassinado (ca-cert.pem)
- Crie uma chave para o certificado do servidor (server-key.pem)
- Gere um certificado para o servidor e assine-o com ca-key.pem (server-cert.pem)
- Crie uma chave para o certificado do cliente (client-key.pem)
- Gere um certificado para o cliente e assine-o com ca-key.pem (client-cert.pem)
Sempre tenha cuidado com a chave privada da CA (ca-key.pem) - qualquer pessoa com acesso a ela pode usá-la para gerar certificados adicionais de cliente ou servidor que serão aceitos como legítimos quando a verificação de CA estiver habilitada. A linha inferior é que todas as chaves devem ser mantidas discretas.
Você pode então adicionar as variáveis relacionadas ao SSL na diretiva [mysqld], por exemplo:
ssl-ca=/etc/ssl/mysql/ca-cert.pem
ssl-cert=/etc/ssl/mysql/server-cert.pem
ssl-key=/etc/ssl/mysql/server-key.pem
Reinicie o servidor MySQL para carregar as alterações. Em seguida, crie um usuário com a instrução REQUIRE SSL, por exemplo:
mysql> GRANT ALL PRIVILEGES ON db1.* TO 'dbuser'@'192.168.1.100' IDENTIFIED BY 'mySecr3t' REQUIRE SSL;
O usuário criado com REQUIRE SSL será forçado a se conectar com os arquivos SSL do cliente corretos (client-cert.pem, client-key.pem e ca-cert.pem).
Com o ClusterControl, a criptografia SSL cliente-servidor pode ser facilmente habilitada a partir da interface do usuário, usando o recurso "Criar criptografia SSL".
Criptografia Galera
Habilitar a criptografia para Galera significa que o IST também será criptografado porque a comunicação acontece através do mesmo soquete. O SST, por outro lado, deve ser configurado separadamente, conforme mostrado na próxima seção. Todos os nós no cluster devem ser habilitados com criptografia SSL e você não pode ter uma combinação de nós em que alguns tenham habilitado a criptografia SSL e outros não. O melhor momento para configurar isso é ao configurar um novo cluster. No entanto, se você precisar adicionar isso em um sistema de produção em execução, infelizmente precisará reinicializar o cluster e haverá tempo de inatividade.
Todos os nós Galera no cluster devem usar a mesma chave, certificado e CA (opcional). Você também pode usar a mesma chave e certificado criado para criptografia cliente-servidor MySQL ou gerar um novo conjunto apenas para essa finalidade. Para ativar a criptografia dentro do Galera, é preciso anexar a opção e o valor em wsrep_provider_options dentro do arquivo de configuração do MySQL em cada nó do Galera. Por exemplo, considere a seguinte linha existente para nosso nó Galera:
wsrep_provider_options = "gcache.size=512M; gmcast.segment=0;"
Anexe as variáveis relacionadas dentro da cotação, delimitadas por um ponto e vírgula:
wsrep_provider_options = "gcache.size=512M; gmcast.segment=0; socket.ssl_cert=/etc/mysql/cert.pem; socket.ssl_key=/etc/mysql/key.pem;"
Para mais informações sobre os parâmetros relacionados ao SSL do Galera, veja aqui. Execute esta modificação em todos os nós. Em seguida, pare o cluster (um nó por vez) e inicie a partir do último nó encerrado. Você pode verificar se o SSL está carregado corretamente examinando o log de erros do MySQL:
2018-01-19T01:15:30.155211Z 0 [Note] WSREP: gcomm: connecting to group 'my_wsrep_cluster', peer '192.168.10.61:,192.168.10.62:,192.168.10.63:'
2018-01-19T01:15:30.159654Z 0 [Note] WSREP: SSL handshake successful, remote endpoint ssl://192.168.10.62:53024 local endpoint ssl://192.168.10.62:4567 cipher: AES128-SHA compression:
Com o ClusterControl, a criptografia Galera Replication pode ser facilmente habilitada usando o recurso "Create SSL Galera Encryption".
Criptografia SST
Quando o SST acontece sem criptografia, a comunicação de dados é exposta enquanto o processo SST está em andamento. SST é um processo de sincronização de dados completo de um doador para um nó de junção. Se um invasor conseguisse "ver" toda a transmissão de dados, a pessoa obteria um instantâneo completo do seu banco de dados.
SST com criptografia é suportado apenas para os métodos mysqldump e xtrabackup-v2. Para mysqldump, o usuário deve receber "REQUIRE SSL" em todos os nós e a configuração é semelhante à criptografia SSL cliente-servidor padrão do MySQL (conforme descrito na seção anterior). Depois que a criptografia cliente-servidor for ativada, crie um novo usuário SST com SSL aplicado:
mysql> GRANT ALL ON *.* TO 'sst_user'@'%' IDENTIFIED BY 'mypassword' REQUIRE SSL;
Para rsync, recomendamos usar galera-secure-rsync, um script SST rsync protegido por SSL drop-in para Galera Cluster. Funciona quase exatamente como wsrep_sst_rsync exceto que protege as comunicações reais com SSL usando socat. Gere a chave de cliente/servidor e os arquivos de certificado necessários, copie-os para todos os nós e especifique o "secure_rsync" como o método SST dentro do arquivo de configuração do MySQL para ativá-lo:
wsrep_sst_method=secure_rsync
Para xtrabackup, as seguintes opções de configuração devem ser habilitadas dentro do arquivo de configuração do MySQL sob a diretiva [sst]:
[sst]
encrypt=4
ssl-ca=/path/to/ca-cert.pem
ssl-cert=/path/to/server-cert.pem
ssl-key=/path/to/server-key.pem
A reinicialização do banco de dados não é necessária. Se este nó for selecionado pelo Galera como doador, essas opções de configuração serão selecionadas automaticamente quando o Galera iniciar o SST.
SELinux
Security-Enhanced Linux (SELinux) é um mecanismo de controle de acesso implementado no kernel. Sem o SELinux, apenas métodos tradicionais de controle de acesso, como permissões de arquivo ou ACL, são usados para controlar o acesso de usuários a arquivos.
Por padrão, com o modo de imposição estrito ativado, tudo é negado e o administrador tem que fazer uma série de políticas de exceções aos elementos do sistema que requerem para funcionar. Desabilitar completamente o SELinux tornou-se uma prática comum para muitas instalações baseadas em RedHat hoje em dia.
Dependendo das cargas de trabalho, padrões de uso e processos, a melhor maneira é criar seu próprio módulo de política SELinux adaptado ao seu ambiente. O que você realmente precisa fazer é definir o SELinux para o modo permissivo (registrando apenas sem forçar) e acionar eventos que podem acontecer em um nó Galera para que o SELinux registre. Quanto mais extenso melhor. Exemplos de eventos como:
- Iniciando nó como doador ou associado
- Reinicie o nó para acionar IST
- Use métodos SST diferentes
- Faça backup e restaure bancos de dados MySQL usando mysqldump ou xtrabackup
- Ativar e desativar logs binários
Um exemplo é se o nó Galera for monitorado pelo ClusterControl e o recurso de monitoramento de consultas estiver ativado, o ClusterControl ativará/desativará a variável de log de consulta lenta para capturar as consultas de execução lenta. Assim, você veria a seguinte negação no audit.log:
$ grep -e denied audit/audit.log | grep -i mysql
type=AVC msg=audit(1516835039.802:37680): avc: denied { open } for pid=71222 comm="mysqld" path="/var/log/mysql/mysql-slow.log" dev="dm-0" ino=35479360 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file
A ideia é permitir que todas as negações possíveis sejam registradas no log de auditoria, que posteriormente pode ser usado para gerar o módulo de política usando audit2allow antes de carregá-lo no SELinux. A codership cobriu isso em detalhes na página de documentação, Configuração do SELinux.
Conta SST e privilégios
SST é um processo de sincronização inicial realizado pelo Galera. Ele atualiza um nó de junção com o restante dos membros do cluster. O processo basicamente exporta os dados do nó doador e os restaura no nó do joiner, antes que o joiner possa acompanhar as transações restantes da fila (ou seja, aquelas que aconteceram durante o processo de sincronização). Três métodos SST são suportados:
- mysqldump
- rsync
- xtrabackup (ou xtrabackup-v2)
Para uso do mysqldump SST, os seguintes privilégios são necessários:
- SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, RELOAD, FILE
Não iremos mais longe com o mysqldump porque provavelmente não é usado com frequência na produção como método SST. Além disso, é um procedimento de bloqueio no doador. O Rsync geralmente é a segunda escolha preferida após o xtrabackup devido ao tempo de sincronização mais rápido e menos propenso a erros em comparação com o mysqldump. A autenticação SST é ignorada com o rsync, portanto, você pode pular a configuração dos privilégios da conta SST se o rsync for o método SST escolhido.
Seguindo com o xtrabackup, os seguintes privilégios são recomendados para procedimentos padrão de backup e restauração com base na página de documentação do Xtrabackup:
- CREATE, CREATE TABLESPACE, EVENT, INSERT, LOCK TABLE, PROCESS, RELOAD, REPLICATION CLIENT, SELECT, SHOW VIEW, SUPER
No entanto, para o uso do SST do xtrabackup, apenas os seguintes privilégios são importantes:
- PROCESSAR, RECARREGAR, CLIENTE DE REPLICAÇÃO
Assim, a instrução GRANT para SST pode ser minimizada como:
mysql> GRANT PROCESS,RELOAD,REPLICATION CLIENT ON *.* TO 'sstuser'@'localhost' IDENTIFIED BY '[email protected]@sTr0nG%%P4ssW0rD';
Em seguida, configure wsrep_sst_auth de acordo com o arquivo de configuração do MySQL:
wsrep_sst_auth = sstuser:[email protected]@sTr0nG%%P4ssW0rD
Conceda apenas o usuário SST para localhost e use uma senha forte. Evite usar o usuário root como a conta SST, pois isso exporia a senha root dentro do arquivo de configuração nesta variável. Além disso, alterar ou redefinir a senha de root do MySQL quebraria o SST no futuro.
Reforço de segurança do MySQL
Galera Cluster é um plug-in de replicação multimestre para o mecanismo de armazenamento InnoDB, que é executado em forks MySQL e MariaDB. Portanto, as recomendações padrão de proteção de segurança do MySQL/MariaDB/InnoDB também se aplicam ao Galera Cluster.
Este tópico foi abordado em vários posts de blog por aí. Também abordamos esse tópico nas seguintes postagens do blog:
- Dez dicas sobre como alcançar a segurança do MySQL e do MariaDB
- Dicas e truques do ClusterControl:protegendo sua instalação do MySQL
- Como proteger seus bancos de dados de código aberto com o ClusterControl
As postagens do blog acima resumem a necessidade de criptografar dados em repouso e dados em trânsito, ter plug-ins de auditoria, diretrizes gerais de segurança, práticas recomendadas de segurança de rede e assim por diante.
Usar um balanceador de carga
Existem vários balanceadores de carga de banco de dados (proxy reverso) que podem ser usados em conjunto com Galera - HAProxy, ProxySQL e MariaDB MaxScale para citar alguns deles. Você pode configurar um balanceador de carga para controlar o acesso aos nós do Galera. É uma ótima maneira de distribuir a carga de trabalho do banco de dados entre as instâncias do banco de dados, bem como restringir o acesso, por exemplo, se você deseja colocar um nó offline para manutenção ou se deseja limitar o número de conexões abertas nos nós do Galera. O balanceador de carga deve ser capaz de enfileirar conexões e, portanto, fornecer alguma proteção contra sobrecarga aos servidores de banco de dados.
ProxySQL, um poderoso proxy reverso de banco de dados que entende MySQL e MariaDB, pode ser estendido com muitos recursos de segurança úteis, como firewall de consulta, para bloquear consultas ofensivas do servidor de banco de dados. O mecanismo de regras de consulta também pode ser usado para reescrever consultas ruins em algo melhor/mais seguro ou redirecioná-las para outro servidor que possa absorver a carga sem afetar nenhum dos nós do Galera. MariaDB MaxScale também é capaz de bloquear consultas baseadas em expressões regulares com seu filtro Database Firewall.
Outra vantagem de ter um balanceador de carga para o Galera Cluster é a capacidade de hospedar um serviço de dados sem expor a camada do banco de dados à rede pública. O servidor proxy pode ser usado como host bastion para obter acesso aos nós do banco de dados em uma rede privada. Ao ter o cluster de banco de dados isolado do mundo exterior, você removeu um dos vetores de ataque importantes.
É isso. Fique sempre seguro e protegido.