Seguridad y DBMS: lo que hay que recordar al elegir herramientas de seguridad

Seguridad y DBMS: lo que hay que recordar al elegir herramientas de seguridad

Mi nombre es Denis Rozhkov, soy el jefe de desarrollo de software de la empresa Gazinformservice, en el equipo de producto. Jatoba. La legislación y las regulaciones corporativas imponen ciertos requisitos para la seguridad del almacenamiento de datos. Nadie quiere que terceros accedan a información confidencial, por lo que las siguientes cuestiones son importantes para cualquier proyecto: identificación y autenticación, gestión del acceso a los datos, garantía de la integridad de la información en el sistema, registro de eventos de seguridad. Por eso, quiero hablar sobre algunos puntos interesantes sobre la seguridad del DBMS.

El artículo fue elaborado a partir de un discurso en @Bases de datosMeetup, organizado Soluciones en la nube Mail.ru. Si no quieres leer, puedes mirar:


El artículo tendrá tres partes:

  • Cómo asegurar las conexiones.
  • ¿Qué es una auditoría de acciones y cómo registrar lo que sucede en la base de datos y conectarse a ella?
  • Cómo proteger los datos de la propia base de datos y qué tecnologías hay disponibles para ello.

Seguridad y DBMS: lo que hay que recordar al elegir herramientas de seguridad
Tres componentes de la seguridad del DBMS: protección de la conexión, auditoría de actividad y protección de datos

Asegurar sus conexiones

Puede conectarse a la base de datos directa o indirectamente a través de aplicaciones web. Como regla general, el usuario empresarial, es decir, la persona que trabaja con el DBMS, interactúa con él de forma indirecta.

Antes de hablar de proteger las conexiones, es necesario responder preguntas importantes que determinan cómo se estructurarán las medidas de seguridad:

  • ¿Un usuario empresarial equivale a un usuario de DBMS?
  • si el acceso a los datos DBMS se proporciona únicamente a través de una API que usted controla o si se accede a las tablas directamente;
  • si el DBMS está asignado a un segmento protegido separado, quién interactúa con él y cómo;
  • si se utilizan agrupación/proxy y capas intermedias, lo que puede cambiar la información sobre cómo se construye la conexión y quién utiliza la base de datos.

Ahora veamos qué herramientas se pueden utilizar para proteger las conexiones:

  1. Utilice soluciones de clase de firewall de base de datos. Una capa adicional de protección aumentará, como mínimo, la transparencia de lo que sucede en el DBMS y, como máximo, podrá proporcionar protección de datos adicional.
  2. Utilice políticas de contraseñas. Su uso depende de cómo esté construida su arquitectura. En cualquier caso, una contraseña en el archivo de configuración de una aplicación web que se conecta al DBMS no es suficiente para la protección. Hay una serie de herramientas DBMS que le permiten controlar que el usuario y la contraseña requieren actualización.

    Puede leer más sobre las funciones de calificación de usuarios. aquí, también puede obtener información sobre los evaluadores de vulnerabilidades de MS SQL aquí

  3. Enriquecer el contexto de la sesión con la información necesaria. Si la sesión es opaca, no comprende quién está trabajando en el DBMS dentro de su marco, puede, en el marco de la operación que se está realizando, agregar información sobre quién está haciendo qué y por qué. Esta información se puede ver en la auditoría.
  4. Configure SSL si no tiene una separación de red entre el DBMS y los usuarios finales; no está en una VLAN separada. En tales casos, es imperativo proteger el canal entre el consumidor y el propio DBMS. Las herramientas de seguridad también están disponibles en código abierto.

¿Cómo afectará esto al rendimiento del DBMS?

Miremos el ejemplo de PostgreSQL para ver cómo SSL afecta la carga de la CPU, aumenta los tiempos y disminuye el TPS, y si consumirá demasiados recursos si lo habilita.

Cargar PostgreSQL usando pgbench es un programa simple para ejecutar pruebas de rendimiento. Ejecuta una única secuencia de comandos repetidamente, posiblemente en sesiones de base de datos paralelas, y luego calcula la tasa de transacción promedio.

Prueba 1 sin SSL y usando SSL — la conexión se establece para cada transacción:

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"

Prueba 2 sin SSL y usando SSL — todas las transacciones se realizan en una sola conexión:

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"

Otros ajustes:

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 de la prueba:

 
SIN SSL
SSL

Se establece una conexión para cada transacción.

promedio de latencia
171.915 ms
187.695 ms

tps incluyendo conexiones estableciendo
58.168112
53.278062

tps excluyendo el establecimiento de conexiones
64.084546
58.725846

CPU
24%
28%

Todas las transacciones se realizan en una sola conexión.

promedio de latencia
6.722 ms
6.342 ms

tps incluyendo conexiones estableciendo
1587.657278
1576.792883

tps excluyendo el establecimiento de conexiones
1588.380574
1577.694766

CPU
17%
21%

Con cargas ligeras, la influencia del SSL es comparable al error de medición. Si la cantidad de datos transferidos es muy grande, la situación puede ser diferente. Si establecemos una conexión por transacción (esto es raro, normalmente la conexión se comparte entre usuarios), tienes un gran número de conexiones/desconexiones, el impacto puede ser un poco mayor. Es decir, puede haber riesgos de disminución del rendimiento, sin embargo, la diferencia no es tan grande como para no utilizar protección.

Tenga en cuenta que existe una gran diferencia si compara los modos de funcionamiento: está trabajando dentro de la misma sesión o en diferentes. Esto es comprensible: se gastan recursos en crear cada conexión.

Tuvimos un caso cuando conectamos Zabbix en modo confianza, es decir, md5 no estaba marcado, no había necesidad de autenticación. Luego, el cliente solicitó habilitar el modo de autenticación md5. Esto supuso una gran carga para la CPU y el rendimiento disminuyó. Comenzamos a buscar formas de optimizar. Una de las posibles soluciones al problema es implementar restricciones de red, crear VLAN separadas para el DBMS, agregar configuraciones para dejar claro quién se conecta desde dónde y eliminar la autenticación. También puede optimizar la configuración de autenticación para reducir los costos al habilitar la autenticación, pero En general, el uso de diferentes métodos de autenticación afecta el rendimiento y requiere tener en cuenta estos factores al diseñar la potencia informática de los servidores (hardware) para el DBMS.

Conclusión: en varias soluciones, incluso los pequeños matices en la autenticación pueden afectar en gran medida el proyecto y es malo cuando esto queda claro solo cuando se implementa en producción.

Auditoría de acción

La auditoría no puede ser solo DBMS. Una auditoría consiste en obtener información sobre lo que sucede en los diferentes segmentos. Puede ser un firewall de base de datos o el sistema operativo en el que se construye el DBMS.

En los DBMS comerciales de nivel empresarial todo está bien con la auditoría, pero en el código abierto, no siempre. Esto es lo que tiene PostgreSQL:

  • registro predeterminado: registro integrado;
  • extensiones: pgaudit: si el registro predeterminado no es suficiente para usted, puede usar configuraciones separadas que resuelven algunos problemas.

Adición al informe en el video:

"El registro de declaraciones básico se puede proporcionar mediante una función de registro estándar con log_statement = all.

Esto es aceptable para monitoreo y otros usos, pero no proporciona el nivel de detalle que normalmente se requiere para la auditoría.

No basta con tener una lista de todas las operaciones realizadas en la base de datos.

También debería ser posible encontrar declaraciones específicas que sean de interés para el auditor.

El registro estándar muestra lo que solicitó el usuario, mientras que pgAudit se centra en los detalles de lo que sucedió cuando la base de datos ejecutó la consulta.

Por ejemplo, es posible que el auditor desee verificar que una tabla en particular se creó dentro de una ventana de mantenimiento documentada.

Esto puede parecer una tarea simple con auditoría y grep básicos, pero ¿qué pasaría si se le presentara algo como este (intencionalmente confuso)?

HACER$$
EMPEZAR
EJECUTAR 'CREAR TABLA importar' || 'ant_table(id int)';
FIN$$;

El registro estándar le dará esto:

REGISTRO: declaración: HACER $$
EMPEZAR
EJECUTAR 'CREAR TABLA importar' || 'ant_table(id int)';
FIN$$;

Parece que encontrar la tabla de interés puede requerir algunos conocimientos de código en los casos en que las tablas se crean dinámicamente.

Esto no es ideal, ya que sería preferible buscar simplemente por nombre de tabla.

Aquí es donde pgAudit resulta útil.

Para la misma entrada, producirá esta salida en el registro:

AUDITORÍA: SESIÓN,33,1,FUNCIÓN,HACER,,,"HACER $$
EMPEZAR
EJECUTAR 'CREAR TABLA importar' || 'ant_table(id int)';
FIN$$;"
AUDITORÍA: SESIÓN, 33,2, DDL, CREAR TABLA, TABLA, public.important_table, CREAR TABLA importante_table (id INT)

No solo se registra el bloque DO, sino también el texto completo de CREATE TABLE con tipo de declaración, tipo de objeto y nombre completo, lo que facilita la búsqueda.

Al registrar declaraciones SELECT y DML, pgAudit se puede configurar para registrar una entrada separada para cada relación a la que se hace referencia en la declaración.

No se requiere análisis para encontrar todas las declaraciones que tocan una tabla en particular (*) ".

¿Cómo afectará esto al rendimiento del DBMS?

Ejecutemos pruebas con la auditoría completa habilitada y veamos qué sucede con el rendimiento de PostgreSQL. Habilitemos el registro máximo de la base de datos para todos los parámetros.

No cambiamos casi nada en el archivo de configuración, lo más importante es activar el modo debug5 para obtener la máxima información.

postgresql.conf

log_destination = 'stderr'
logging_collector = activado
log_truncate_on_rotation = activado
log_rotation_age = 1d
log_rotation_size = 10 MB
log_min_messages = depurar5
log_min_error_statement = depurar5
log_min_duration_statement = 0
debug_print_parse = activado
debug_print_rewrite = activado
debug_print_plan = activado
debug_pretty_print = activado
log_checkpoints = activado
log_connections = encendido
log_disconnections = encendido
log_duration = activado
log_hostname = activado
log_lock_waits = encendido
log_replication_commands = activado
registro_temp_archivos = 0
log_timezone = 'Europa/Moscú'

En un DBMS PostgreSQL con parámetros de 1 CPU, 2,8 GHz, 2 GB de RAM, 40 GB de disco duro, realizamos tres pruebas de carga utilizando los 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

Resultados de la prueba:

Sin registro
con registro

Tiempo total de llenado de la base de datos
43,74 sec
53,23 sec

robo
24%
40%

CPU
72%
91%

Prueba 1 (50 conexiones)

Número de transacciones en 10 minutos
74169
32445

Transacciones/seg
123
54

latencia media
405 ms
925 ms

Prueba 2 (150 conexiones con 100 posibles)

Número de transacciones en 10 minutos
81727
31429

Transacciones/seg
136
52

latencia media
550 ms
1432 ms

Acerca de los tamaños

tamaño de base de datos
2251 MB
2262 MB

Tamaño del registro de la base de datos
0 MB
4587 MB

En pocas palabras: una auditoría completa no es muy buena. Los datos de la auditoría serán tan grandes como los datos de la propia base de datos, o incluso más. La cantidad de registros que se genera al trabajar con un DBMS es un problema común en producción.

Veamos otros parámetros:

  • La velocidad no cambia mucho: sin iniciar sesión - 43,74 segundos, con iniciar sesión - 53,23 segundos.
  • El rendimiento de la RAM y la CPU se verá afectado, ya que necesitará generar un archivo de auditoría. Esto también se nota en la productividad.

A medida que aumenta el número de conexiones, naturalmente, el rendimiento se deteriorará ligeramente.

En las corporaciones con auditoría es aún más difícil:

  • hay muchos datos;
  • la auditoría es necesaria no solo a través de syslog en SIEM, sino también de los archivos: si algo le sucede a syslog, debe haber un archivo cerca de la base de datos en la que se guardan los datos;
  • se necesita un estante separado para la auditoría para no desperdiciar discos de E/S, ya que ocupa mucho espacio;
  • Sucede que los empleados de seguridad de la información necesitan estándares GOST en todas partes, requieren identificación estatal.

Restringir el acceso a los datos

Veamos las tecnologías que se utilizan para proteger los datos y acceder a ellos en DBMS comerciales y de código abierto.

¿Qué puedes usar generalmente?

  1. Cifrado y ofuscación de procedimientos y funciones (envoltura), es decir, herramientas y utilidades independientes que hacen que el código legible sea ilegible. Es cierto que entonces no se puede cambiar ni refactorizar. Este enfoque a veces es necesario al menos en el lado del DBMS: la lógica de las restricciones de licencia o la lógica de autorización está cifrada precisamente en el nivel de procedimiento y función.
  2. La limitación de la visibilidad de los datos por filas (RLS) se produce cuando diferentes usuarios ven una tabla, pero una composición diferente de filas en ella, es decir, algo no se puede mostrar a alguien en el nivel de fila.
  3. La edición de los datos mostrados (Enmascaramiento) ocurre cuando los usuarios en una columna de la tabla ven datos o solo asteriscos, es decir, para algunos usuarios la información se cerrará. La tecnología determina a qué usuario se le muestra qué según su nivel de acceso.
  4. El control de acceso a DBA de seguridad/DBA de aplicaciones/DBA consiste, más bien, en restringir el acceso al propio DBMS, es decir, los empleados de seguridad de la información pueden separarse de los administradores de bases de datos y de aplicaciones. Hay pocas tecnologías de este tipo en código abierto, pero hay muchas en los DBMS comerciales. Son necesarios cuando hay muchos usuarios con acceso a los propios servidores.
  5. Restringir el acceso a archivos a nivel del sistema de archivos. Puede otorgar derechos y privilegios de acceso a directorios para que cada administrador tenga acceso solo a los datos necesarios.
  6. Acceso obligatorio y borrado de memoria: estas tecnologías rara vez se utilizan.
  7. El cifrado de extremo a extremo directamente desde el DBMS es un cifrado del lado del cliente con administración de claves en el lado del servidor.
  8. Cifrado de datos. Por ejemplo, el cifrado de columnas se produce cuando se utiliza un mecanismo que cifra una sola columna de la base de datos.

¿Cómo afecta esto al rendimiento del DBMS?

Veamos el ejemplo de cifrado de columnas en PostgreSQL. Hay un módulo pgcrypto que le permite almacenar campos seleccionados en forma cifrada. Esto es útil cuando sólo algunos datos son valiosos. Para leer los campos cifrados, el cliente transmite una clave de descifrado, el servidor descifra los datos y los devuelve al cliente. Sin la clave, nadie puede hacer nada con tus datos.

Probemos con pgcrypto. Creemos una tabla con datos cifrados y datos regulares. A continuación se muestran los comandos para crear tablas, en la primera línea hay un comando útil: crear la extensión en sí con el registro 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'));

A continuación, intentemos hacer una muestra de datos de cada tabla y observar los tiempos de ejecución.

Seleccionar de una tabla sin función de cifrado:

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

El cronómetro está encendido.

  identificación | texto1 | texto2
——+——-+——-
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
...
997 | 997 | 997
998 | 998 | 998
999 | 999 | 999
1000 | 1000 | 1000
(1000 líneas)

Tiempo: 1,386 ms

Selección de una tabla con función de cifrado:

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

El cronómetro está encendido.

  identificación | descifrar | descifrar
——+—————+————
1 | x31 | x31
2 | x32 | x32
3 | x33 | x33
...
999 | x393939 | x393939
1000 | x31303030 | x31303030
(1000 líneas)

Tiempo: 50,203 ms

Resultados de la prueba:

 
sin encriptación
Pgcrypto (descifrar)

Muestra 1000 filas
1,386 ms
50,203 ms

CPU
15%
35%

robo
 
+ 5%

El cifrado tiene un gran impacto en el rendimiento. Se puede ver que el tiempo ha aumentado, ya que las operaciones de descifrado de datos cifrados (y el descifrado generalmente todavía está incluido en su lógica) requieren recursos importantes. Es decir, la idea de cifrar todas las columnas que contienen algunos datos conlleva una disminución del rendimiento.

Sin embargo, el cifrado no es una solución milagrosa que resuelva todos los problemas. Los datos descifrados y la clave de descifrado durante el proceso de descifrado y transmisión de datos se encuentran en el servidor. Por lo tanto, las claves pueden ser interceptadas por alguien que tenga acceso total al servidor de la base de datos, como un administrador del sistema.

Cuando hay una clave para toda la columna para todos los usuarios (aunque no para todos, sino para los clientes de un conjunto limitado), esto no siempre es bueno y correcto. Es por eso que comenzaron a realizar cifrado de extremo a extremo, en el DBMS comenzaron a considerar opciones para cifrar datos en el lado del cliente y del servidor, y aparecieron esos mismos almacenes de claves: productos separados que brindan administración de claves en el DBMS. lado.

Seguridad y DBMS: lo que hay que recordar al elegir herramientas de seguridad
Un ejemplo de este tipo de cifrado en MongoDB

Funciones de seguridad en DBMS comerciales y de código abierto

funciones
tipo
Política de contraseñas
Auditoría
Proteger el código fuente de procedimientos y funciones.
RLS
Cifrado

Oracle
comercial
+
+
+
+
+

MsSql
comercial
+
+
+
+
+

Jatoba
comercial
+
+
+
+
extensiones

PostgreSQL
Gratuito
extensiones
extensiones
-
+
extensiones

mongodb
Gratuito
-
+
-
-
Disponible solo en MongoDB Enterprise

La tabla está lejos de estar completa, pero la situación es la siguiente: en los productos comerciales, los problemas de seguridad se han resuelto durante mucho tiempo, en el código abierto, por regla general, se utilizan algún tipo de complementos para la seguridad, faltan muchas funciones , a veces hay que añadir algo. Por ejemplo, políticas de contraseñas: PostgreSQL tiene muchas extensiones diferentes (1, 2, 3, 4, 5), que implementan políticas de contraseñas, pero, en mi opinión, ninguna de ellas cubre todas las necesidades del segmento corporativo nacional.

Qué hacer si no tienes lo que necesitas en ningún lado? Por ejemplo, desea utilizar un DBMS específico que no tiene las funciones que requiere el cliente.

Luego, puede utilizar soluciones de terceros que funcionen con diferentes DBMS, por ejemplo, Crypto DB o Garda DB. Si hablamos de soluciones del segmento nacional, entonces conocen los GOST mejor que los de código abierto.

La segunda opción es escribir lo que necesita usted mismo, implementar el acceso a los datos y el cifrado en la aplicación a nivel de procedimiento. Es cierto que con GOST será más difícil. Pero, en general, puede ocultar los datos según sea necesario, colocarlos en un DBMS, luego recuperarlos y descifrarlos según sea necesario, directamente en el nivel de la aplicación. Al mismo tiempo, piense inmediatamente en cómo protegerá estos algoritmos en la aplicación. En nuestra opinión, esto debería hacerse a nivel de DBMS, porque funcionará más rápido.

Este informe fue presentado por primera vez en @Reunión de bases de datos por Mail.ru Soluciones en la nube. Mirar видео otras actuaciones y suscríbete a anuncios de eventos en Telegram Acerca de Kubernetes en Mail.ru Group.

¿Qué más leer sobre el tema?:

  1. Más que Ceph: almacenamiento en bloques en la nube MCS.
  2. Cómo elegir una base de datos para un proyecto para no tener que volver a elegir.

Fuente: habr.com

Añadir un comentario