Segurança e DBMS: o que você precisa lembrar ao escolher as ferramentas de proteção


Meu nome é Denis Rozhkov, sou o chefe de desenvolvimento de software da Gazinformservice, na equipe de produtos Jatoba . A legislação e os regulamentos corporativos impõem certos requisitos para a segurança do armazenamento de dados. Ninguém deseja que terceiros obtenham acesso a informações confidenciais; portanto, os seguintes problemas são importantes para qualquer projeto: identificação e autenticação, gerenciamento de acesso a dados, garantia da integridade das informações no sistema, registro de eventos de segurança. Portanto, quero falar sobre alguns pontos interessantes sobre a segurança do DBMS.

Este artigo foi escrito por @Databases Meetup, hospedado por Mail.ru Cloud Solutions . Se você não quiser ler, poderá ver:


O artigo terá três partes:

  • Como proteger conexões.
  • O que é uma auditoria de ações e como registrar o que está acontecendo por parte do banco de dados e a conexão com ele.
  • Como proteger os dados no próprio banco de dados e quais tecnologias existem para isso.


Os três componentes da segurança do DBMS: proteção de conexão, auditoria de atividades e proteção de dados

Proteção de conexão


Você pode se conectar ao banco de dados direta ou indiretamente por meio de aplicativos da web. Como regra, o usuário do lado da empresa, ou seja, a pessoa que trabalha com o DBMS, não interage diretamente com ele.

Antes de falar sobre a proteção de conexões, você precisa responder a perguntas importantes que dependem de como as medidas de segurança serão construídas:

  • se um usuário comercial é equivalente a um usuário DBMS;
  • O acesso aos dados do DBMS é fornecido apenas por meio da API que você controla ou há acesso diretamente às tabelas;
  • se o DBMS está alocado em um segmento protegido separado, quem interage com ele e como;
  • se pool / proxy e middleware são usados, o que pode alterar as informações sobre como a conexão é construída e quem usa o banco de dados.

Agora vamos ver quais ferramentas podem ser usadas para proteger conexões:

  1. Use soluções de classe de firewall de banco de dados. Uma camada adicional de proteção, pelo menos, aumentará a transparência do que está acontecendo no DBMS, no máximo - você pode fornecer proteção adicional aos dados.
  2. . , . — -, , . , , .

    , MS SQL Vulnerability Assessmen
  3. . , , , , , . .
  4. Configure o SSL, se você não tiver uma separação de rede do DBMS dos usuários finais, ele não estará em uma VLAN separada. Nesses casos, é necessário proteger o canal entre o consumidor e o próprio DBMS. As ferramentas de proteção estão entre o código aberto.

Como isso afetará o desempenho do DBMS?


Vejamos um exemplo do PostgreSQL, como o SSL afeta a carga da CPU, aumentando os tempos e diminuindo o TPS, se houver muitos recursos, se você o habilitar.

Carregamos o PostgreSQL usando o pgbench - é um programa simples para executar testes de desempenho. Ele executa repetidamente uma sequência de comandos, possivelmente em sessões paralelas de banco de dados, e calcula a velocidade média da transação.

Teste 1 sem SSL e usando SSL - uma conexão é estabelecida com cada transação:

pgbench.exe --connect -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres sslmode=require 
sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key"

vs

pgbench.exe --connect -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres"

Teste 2 sem SSL e usando SSL - todas as transações são executadas em uma conexão:

pgbench.exe -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres sslmode=require
sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key"

vs

pgbench.exe -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres"

Outras configurações :

scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 5000
number of transactions actually processed: 50000/50000

Resultados do teste :
 SEM SSLSSL
A conexão é estabelecida em cada transação
média de latência171.915 ms187.695 ms
tps, incluindo conexões que estabelecem58.16811253.278062
tps excluindo conexões que estabelecem64.08454658.725846
CPU24%28%
Todas as transações são realizadas em uma conexão.
média de latência6,722 ms6.342 ms
tps incluindo conexões que estabelecem1587.6572781576.792883
tps excluindo conexões que estabelecem1588.3805741577.694766
CPU17%21%

Em cargas leves, o efeito do SSL é comparável ao erro de medição. Se a quantidade de dados transferidos for muito grande, a situação poderá ser diferente. Se estabelecermos uma conexão para cada transação (isso é raro, geralmente a conexão é compartilhada entre usuários), você tem um grande número de conexões / desconexões, o efeito pode ser um pouco mais. Ou seja, pode haver riscos para a degradação do desempenho, no entanto, a diferença não é tão grande que não use proteção.

Observe que há uma grande diferença ao comparar os modos de operação: na mesma sessão, você trabalha ou é diferente. Isso é compreensível: os recursos são gastos na criação de cada conexão.

Tivemos um caso quando conectamos o Zabbix no modo de confiança, ou seja, não verificamos o md5, não havia necessidade de autenticação. Em seguida, o cliente pediu para ativar o modo de autenticação md5. Isso deu uma grande carga na CPU, o desempenho diminuiu. Eles começaram a procurar maneiras de otimizar. Uma das soluções possíveis para o problema é implementar uma restrição de rede, criar VLANs separadas para o DBMS, adicionar configurações para que fique claro quem está se conectando de onde e remover a autenticação.Você também pode otimizar as configurações de autenticação para reduzir os custos de habilitar a autenticação, mas em geral, usando vários métodos a autenticação afeta o desempenho e exige que esses fatores sejam considerados ao projetar o poder de computação dos servidores (hardware) para um DBMS.

Conclusão: em várias soluções, até pequenas nuances de autenticação podem afetar muito o projeto e é ruim quando fica claro apenas quando implementado em um produto.

Auditoria de ações


Uma auditoria pode ser não apenas um DBMS. Auditoria é o recebimento de informações sobre o que está acontecendo em diferentes segmentos. Pode ser um firewall de banco de dados e o sistema operacional no qual o DBMS é construído.

Nos DBMSs comerciais de nível empresarial com auditoria, tudo está bem, em código aberto - nem sempre. Aqui está o que o PostgreSQL possui:

  • log padrão - log embutido;
  • extensions: pgaudit - se você não tiver um registro padrão suficiente, poderá usar configurações separadas que resolvam alguns dos problemas.

Além do relatório no vídeo:

“O registro básico de operadores pode ser fornecido com o recurso de registro padrão com log_statement = all.

Isso é aceitável para monitoramento e outros usos, mas não fornece o nível de detalhe normalmente necessário para uma auditoria.

Não basta ter uma lista de todas as operações executadas com o banco de dados.

Também deve ser possível encontrar declarações específicas que sejam do interesse do auditor.

A ferramenta de registro padrão mostra o que o usuário solicitou, enquanto o pgAudit se concentra nos detalhes do que aconteceu quando o banco de dados fez a solicitação.

Por exemplo, o auditor pode querer garantir que uma tabela específica tenha sido criada em uma janela de manutenção documentada.

Pode parecer uma tarefa simples para auditoria básica e grep, mas e se você encontrar algo parecido com este exemplo (intencionalmente confuso):

DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

O log padrão fornece o seguinte:

LOG: instrução: DO $$
BEGIN
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

Parece que a procura de uma tabela de interesse pode exigir algum conhecimento de código nos casos em que as tabelas são criadas dinamicamente.

Isso não é o ideal, pois seria preferível pesquisar apenas pelo nome da tabela.

É aqui que o pgAudit será útil.

Para a mesma entrada, ela produzirá esta saída no log:

AUDITORIA: SESSÃO, 33.1, FUNCTION, DO ,,, “DO $$
COMEÇA A
EXECUTAR 'CREATE TABLE import' || 'ant_table (id INT)';
END $$; "
AUDIT: SESSION, 33,2, DDL, CREATE TABLE, TABLE, public.important_table, CREATE TABLE important_table (id INT)

Não apenas o bloco DO está registrado, mas também o texto completo CREATE TABLE com o tipo de operador, tipo de objeto e nome completo, facilitando a pesquisa.

na conduta da revista de operadores SELECT e DML pgAudit pode ser configurada para registrar uma entrada separada para cada relacionamento, que é referenciado na instrução.

Não é necessário analisar para localizar todas as instruções relacionadas a uma tabela específica ( * ) " .

Como isso afetará o desempenho do DBMS?


Vamos executar os testes com a auditoria completa ativada e ver o que acontece com o desempenho do PostgreSQL. Ativamos o log máximo do banco de dados em todos os aspectos.

Quase não mudamos nada no arquivo de configuração, desde o importante - ative o modo debug5 para obter o máximo de informações.

postgresql.conf
log_destination = 'stderr'
logging_collector = on
log_truncate_on_rotation = on
log_rotation_age = 1d
log_rotation_size = 10MB
log_min_messages = debug5
log_min_error_statement = debug5
log_min_duration_statement = 0
debug_print_parse =
debug_print_rewritten = em
debug_print_plan = em
debug_pretty_print = em
log_checkpoints = em
log_connections = em
log_disconnections = em
log_duration = em
log_hostname = em
log_lock_waits = em
log_replication_commands = em
log_temp_files = 0
log_timezone =

No DBMS do PostgreSQL com os parâmetros 1 CPU, 2,8 GHz, 2 GB de RAM, 40 GB de disco rígido, realizamos três testes de carga usando os seguintes comandos:

$ pgbench -p 3389 -U postgres -i -s 150 benchmark
$ pgbench -p 3389 -U postgres -c 50 -j 2 -P 60 -T 600 benchmark
$ pgbench -p 3389 -U postgres -c 150 -j 2 -P 60 -T 600 benchmark

Resultado dos testes:
Sem registroCom registro
Tempo total de preenchimento do banco de dados43,74 seg53,23 seg
RAM24%40%
CPU72%91%
Teste 1 (50 conexões)
Número de transações em 10 minutos7416932445
Transação / s12354
Atraso médio405 ms925 ms
Teste 2 (150 conexões a 100 possíveis)
Número de transações em 10 minutos8172731429
Transação / s13652
Atraso médio550 ms1432 ms
Sobre tamanhos
Tamanho do banco de dados2251 MB2262 MB
Tamanho do log do banco de dados0 Mb4587 Mb

Conclusão: uma auditoria completa não é muito boa. Os dados da auditoria sairão em volume, como os dados no próprio banco de dados, ou até mais. A quantidade de log que é gerada ao trabalhar com o DBMS é um problema comum no produto.

Examinamos outros parâmetros:

  • A velocidade não muda muito: sem registro - 43,74 segundos, com registro - 53,23 seg.
  • O desempenho na RAM e na CPU diminuirá, pois você precisará criar um arquivo com a auditoria. Também é perceptível no produtivo.

Com um aumento no número de conexões, é claro, o desempenho se deteriorará levemente.

Nas empresas com auditoria, é ainda mais difícil:

  • há muitos dados;
  • a auditoria é necessária não apenas por meio do syslog no SIEM, mas também dos arquivos: de repente algo acontece com o syslog, o arquivo no qual os dados são salvos deve estar próximo ao banco de dados;
  • a auditoria requer uma prateleira separada, para não afundar nos discos de E / S, pois ocupa muito espaço;
  • acontece que os funcionários de SI precisam de GOSTs em todos os lugares, eles exigem identificação de convidados.

Restrição de acesso a dados


Vejamos as tecnologias usadas para proteger os dados e acessá-los no DBMS comercial e no código aberto.

O que pode ser usado como um todo:

  1. Criptografia e ofuscação de procedimentos e funções (quebra automática) - ou seja, ferramentas e utilitários separados que tornam o código ilegível do código legível. É verdade que não pode ser alterado nem refatorado. Essa abordagem às vezes é necessária pelo menos no lado do DBMS - a lógica das restrições de licenciamento ou a lógica de autorização é criptografada precisamente no nível do procedimento e da função.
  2. (RLS) — , , - - .
  3. (Masking) — , , - . , .
  4. Security DBA/Application DBA/DBA — , , , database- application-. open source , . , .
  5. . , , .
  6. — .
  7. End-to-end encryption — client-side .
  8. . , — , .

?


Vejamos um exemplo de criptografia de coluna no PostgreSQL. Existe um módulo pgcrypto, que permite armazenar campos selecionados em formato criptografado. Isso é útil quando apenas alguns dados são valiosos. Para ler os campos criptografados, o cliente passa a chave de descriptografia, o servidor descriptografa os dados e os emite para o cliente. Sem uma chave com seus dados, ninguém pode fazer nada.

Vamos testar com pgcrypto . Crie uma tabela com dados criptografados e dados regulares. Abaixo está o comando para criar tabelas; na primeira linha, um comando útil está criando a própria extensão com o registro do DBMS:

CREATE EXTENSION pgcrypto;
CREATE TABLE t1 (id integer, text1 text, text2 text);
CREATE TABLE t2 (id integer, text1 bytea, text2 bytea);
INSERT INTO t1 (id, text1, text2)
VALUES (generate_series(1,10000000), generate_series(1,10000000)::text, generate_series(1,10000000)::text);
INSERT INTO t2 (id, text1, text2) VALUES (
generate_series(1,10000000),
encrypt(cast(generate_series(1,10000000) AS text)::bytea, 'key'::bytea, 'bf'),
encrypt(cast(generate_series(1,10000000) AS text)::bytea, 'key'::bytea, 'bf'));

Em seguida, tentaremos fazer amostragem de dados de cada tabela e examinar os tempos de execução.

Seleção da tabela sem função de criptografia :

psql -c "\timing" -c "select * from t1 limit 1000;" "host=192.168.220.129 dbname=taskdb
user=postgres sslmode=disable" > 1.txt

O cronômetro está ativado.

  id | texto1 | text2
------ + ------- + -------
1 | 1 | 1
2 2 2
3 | 3 3
...
997 | 997 997
998 998 998.999
| 999 999
1000 | 1000 1000
(1000 linhas)

Tempo: 1.386 ms

Amostragem de uma tabela com função de criptografia:

psql -c "\timing" -c "select id, decrypt(text1, 'key'::bytea, 'bf'),
decrypt(text2, 'key'::bytea, 'bf') from t2 limit 1000;"
"host=192.168.220.129 dbname=taskdb user=postgres sslmode=disable" > 2.txt

O cronômetro está ativado.

  id | descriptografar | descriptografar
----- + -------------- + ------------
1 | \ x31 | \ x31
2 | \ x32 | \ x32
3 | \ x33 | \ x33
...
999 | \ x393939 | \ x393939
1000 | \ x31303030 | \ x31303030
(1000 linhas)

Tempo: 50,203 ms

Resultados do teste :
 Sem criptografiaPgcrypto (descriptografar)
Busca de 1000 linhas1.386 ms50.203 ms
CPUquinze%35%
RAM + 5%

A criptografia tem um grande impacto no desempenho. Pode-se observar que o tempo aumentou, pois as operações de descriptografar dados criptografados (e a descriptografia geralmente ainda estão encapsuladas em sua lógica) requerem recursos significativos. Ou seja, a idéia de criptografar todas as colunas que contêm algum tipo de dados é repleta de desempenho reduzido.

No entanto, a criptografia não é uma bala de prata que resolve todos os problemas. Os dados descriptografados e a chave de descriptografia no processo de descriptografia e transferência de dados estão localizados no servidor. Portanto, as chaves podem ser interceptadas por quem tem acesso total ao servidor de banco de dados, por exemplo, um administrador do sistema.

Quando a coluna inteira para todos os usuários tem uma chave (mesmo que não seja para todos, mas para um conjunto limitado de clientes), isso nem sempre é bom e correto. É por isso que eles começaram a criptografar de ponta a ponta; no DBMS, começaram a considerar opções para criptografar dados do cliente e do servidor, os mesmos repositórios de cofre de chaves que apareceram - produtos separados que fornecem gerenciamento de chaves no DBMS.


Um exemplo dessa criptografia no MongoDB

Recursos de segurança em DBMS comercial e de código aberto


FunçõesUm tipoPolítica de senhaAuditarProtegendo o código-fonte para procedimentos e funçõesRLSCriptografia
Oráculocomercial+++++
Msqlcomercial+++++
Jatobácomercial++++extensões
PostgreSQLLivreextensõesextensões-+extensões
MongodbLivre-+--Disponível apenas no MongoDB Enterprise

A tabela está longe de estar completa, mas a situação é a seguinte: em produtos comerciais, os problemas de segurança foram resolvidos por um longo tempo, em código aberto, como regra, alguns complementos são usados ​​para segurança, muitas funções não são suficientes, às vezes você precisa adicionar algo. Por exemplo, políticas de senha - no PostgreSQL existem muitas extensões diferentes ( 1 , 2 , 3 , 4 , 5 ) que implementam políticas de senha, mas, na minha opinião, nenhuma cobre todas as necessidades do segmento corporativo doméstico.

O que fazer se não for necessário em lugar algum ? Por exemplo, quero usar um DBMS específico, no qual não há funções que o cliente exija.

Em seguida, você pode usar soluções de terceiros que funcionam com diferentes DBMSs, por exemplo, “Crypto DB” ou “Garda DB”. Se estamos falando de soluções do segmento doméstico, eles sabem melhor sobre GOSTs do que em código aberto.

A segunda opção é escrever o que você precisa, implementar acesso e criptografia de dados no aplicativo no nível do procedimento. É verdade que, com o GOST, será mais difícil. Mas, em geral - você pode ocultar os dados conforme necessário, colocá-los no DBMS, obtê-los e descriptografá-los como deveriam, diretamente no nível do aplicativo. Ao mesmo tempo, pense imediatamente em como você protegerá esses algoritmos no aplicativo. Em nossa opinião, isso deve ser feito no nível do DBMS, porque funcionará mais rapidamente.

Essa palestra foi feita pela primeira vez no @Databases Meetup pelo Mail.ru Cloud Solutions. Assista ao vídeooutras aparições e inscreva-se nos anúncios de eventos do Telegram Around Kubernetes no Mail.ru Group .

O que mais se pode ler sobre o tópico :

  1. Mais do que Ceph: MCS Block Cloud Storage .
  2. Como escolher um banco de dados para o projeto, para não selecionar novamente .

All Articles