Servidor Couchbase 5.5 incluye la capacidad de mantener un registro de todas las acciones N1QL realizadas por los usuarios. Esto es parte de la funcionalidad más general de Couchbase. auditoría introducida en la versión 5.0. La auditoría sólo está disponible en la edición Enterprise.
La auditoría permite a los administradores del sistema saber quién accede a qué datos del sistema. Esto es importante cuando los datos almacenados son sensibles de alguna manera, como información sobre usuarios. Couchbase Server 5.5 soporta auditoría de sentencias N1QL, y permite al administrador especificar qué tipos de sentencias (SELECTs? INSERTs?) deberían ser auditadas.
Es importante entender lo que Couchbase Server 5.5 no hace. En particular, no permite auditoría a nivel de registro. Si se ejecuta una sentencia UPDATE y modifica cinco registros, el registro de auditoría incluirá la sentencia completa que se ejecutó, incluyendo cualquier parámetro pasado, y dirá que se actualizaron cinco registros. No dirá qué registros específicos fueron actualizados, o cuáles eran sus valores antes o después de la operación. Fundamentalmente, la auditoría N1QL audita sentencias, no registros.
Para configurar la auditoría, inicie sesión en la consola de administración de Couchbase. Navega a la pestaña Seguridad (en el lateral) y a la pestaña Auditoría (en la parte superior de la pantalla). Ahora debería ver una pantalla como esta:
Esta pestaña le permite configurar la auditoría en general. La casilla de verificación situada en la parte superior indica si debe realizarse alguna auditoría. "Directorio de registro de destino" muestra dónde colocar los registros de auditoría. Los registros aparecen en un archivo llamado "audit.log" en el directorio de registro de destino. El siguiente conjunto de cuadros de texto controla la rotación del registro por tamaño e intervalo de tiempo.
A continuación hay tres menús desplegables para distintos tipos de eventos, que le permiten controlar con precisión qué tipo de actividades deben registrarse. En general, audite sólo lo que deba. El coste real de rendimiento de la auditoría depende de cuánto se audite y del tipo de extractos que se auditen. Un diez por ciento de pérdida de rendimiento debido a la auditoría es una estimación razonable, pero debería comprobar el efecto real antes de implantar un nuevo sistema.
Por último, puede crear una lista blanca de usuarios en la casilla "Ignorar eventos de estos usuarios". Se trata de usuarios en los que se confía tanto que no es necesario registrar sus acciones. Por ejemplo, puede tener un script automatizado que inserte nuevos datos. Usted confía plenamente en este script. Crear un usuario en la lista blanca y hacer que el script utilice las credenciales de ese usuario puede ser útil para evitar generar demasiados registros de auditoría.
Activa el desplegable "Eventos N1QL", para ver los tipos de eventos disponibles para N1QL.
Existen dos tipos generales. El primero son los eventos correspondientes a los tipos de sentencia N1QL. Por ejemplo, puede elegir auditar todos los eventos INSERT, o todos los eventos DELETE. Por ejemplo, podría ser razonable auditar todos los eventos que modifican datos (INSERT/DELETE/UPDATE/UPSERT), pero ignorar las sentencias que sólo recuperan datos (SELECT).
En segundo lugar están los eventos correspondientes a las APIs expuestas por el motor de consulta. El motor de consulta N1QL pone a disposición una serie de APIs, normalmente para monitorizar el sistema. Cada uno de estos puntos finales API es un tipo de evento separado. Por ejemplo, hay uno para el endpoint /admin/stats, y otro para el endpoint /admin/ping. Usted tiene control separado sobre si auditar o no los accesos a estas APIs.
Consulta simple
Comenzaremos auditando una simple sentencia SELECT.
Vaya a la página "Buckets" de la consola de administración y cree un bucket llamado "test" (sin comillas). La cuota de memoria de 100 MB está bien para nuestros propósitos. A continuación, vaya a la consulta y crear un índice primario en el nuevo cubo, que nos permita ejecutar consultas N1QL en él.
crear índice primario en test
Vuelve a la pantalla de configuración de la auditoría y selecciona "Auditar eventos y escribirlos en un registro" en la parte superior, y la opción "SELECT statement" en "Eventos N1QL". A continuación, pulse "Guardar" en la parte inferior de la pantalla.
A continuación, ejecute una consulta como ésta.
curl http://localhost:8093/query/service -d "statement=select * from test" -u Administrador:contraseña
Y echemos un vistazo al registro de auditoría. El campo "Target Log Directory" de la pantalla de configuración de la auditoría tiene el directorio donde se almacena el registro de auditoría. Utilizaremos el comando "tail" para mostrar los últimos registros del log de auditoría en este directorio. En sistemas Mac, este comando funciona:
tail ~/Library/Application\ Support/Couchbase/var/lib/couchbase/logs/audit.log
Debería ver varias líneas largas de texto JSON. Cada línea es un registro de auditoría. La última es el registro de la declaración que enviamos. Reformateado, se ve así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ "timestamp": "2018-03-14T05:53:34.976-07:00", "real_userid": { "fuente": "local", "usuario": "Administrador" }, "requestId": "d0554df3-fd99-40f5-b911-b3e4f0faf050", "declaración": "select * from test", "isAdHoc": verdadero, "userAgent": "curl\/7.43.0", "nodo": "127.0.0.1:8091", "status": "éxito", "métricas": { "tiempo transcurrido": "822.147u00b5s", "executionTime": "785.755\u00b5s", "resultCount": 0, "resultSize": 0 }, "id": 28672, "nombre": "Declaración SELECT", "descripción": "Se ejecutó una sentencia N1QL SELECT" } |
Vayamos campo por campo:
- "timestamp" muestra la hora del nodo de consulta.
- "real_userid" muestra qué credencial de usuario se suministró con la solicitud. En este caso se trata del usuario "Administrador".
- "requestId" es el UUID que el motor de consultas genera para cada solicitud. Estos ID son únicos con una probabilidad muy alta.
- "statement" es la sentencia real que ejecutamos.
- "isAdHoc" es verdadero en este caso, mostrando que enviamos una sentencia real para su ejecución, en lugar de ejecutar una sentencia preparada.
- "userAgent" es la cadena User-Agent de la petición original. Esto es útil para distinguir si la solicitud procede de un SDK, del intérprete de comandos CBQ o del Query WorkBench.
- "nodo" es la dirección IP desde la que se recibió la solicitud.
- "status" muestra qué ha pasado con la solicitud. En este caso, ha tenido éxito.
- "métricas" es un conjunto de estadísticas sobre el resultado. Coincide con las métricas que se enviaron con el resultado de la solicitud original.
- "id" es el ID del tipo de evento. Los registros de auditoría de todas las consultas SELECT tienen el mismo id, 28672.
- "nombre" es el nombre corto del tipo de evento. Será el mismo para todas las consultas SELECT.
- "descripción" es el nombre largo del tipo de evento. Esto también es igual para todas las consultas SELECT.
Tenga en cuenta que el registro de auditoría sólo proporciona un usuario, aunque el motor de consulta permite múltiples credenciales por solicitud. Esto es por diseño. N1QL permitía múltiples credenciales para consultas cuando nuestras credenciales eran por contenedor, y múltiples credenciales eran por lo tanto necesarias para uniones de múltiples contenedores. Pero a partir de la versión 5.0, con RBAC, las credenciales múltiples ya no son necesarias. Las admitimos por compatibilidad con versiones anteriores, pero la forma correcta de gestionar estos casos es crear usuarios con credenciales para varios buckets y utilizar uno de esos usuarios para cada consulta. Si insiste en utilizar varias credenciales para una consulta auditada, la consulta se auditará, pero habrá un registro de auditoría distinto para cada credencial suministrada. Esto es un poco incómodo, por lo que sugerimos encarecidamente actualizar el modelo de permisos para utilizar permisos RBAC en estos casos.
Preparar la declaración
Consideremos ahora un caso más sofisticado, con una sentencia preparada. En primer lugar, vuelva a la pantalla de configuración de la auditoría y active la auditoría de las sentencias SELECT y PREPARE. Recuerde pulsar "Guardar" en la parte inferior de la pantalla.
Ahora, primero prepararemos una sentencia. Aquí estamos preparando una sentencia SELECT, con el nombre "ejemplo". Observe que la sentencia tiene un parámetro sin nombre.
curl http://localhost:8093/query/service -d "statement=prepare example as select * from test where one=?" -u Administrador:contraseña
A continuación, ejecutaremos la sentencia, proporcionando un argumento para la sentencia. En este caso, la sentencia se ejecutará, pero no devolverá ningún resultado.
curl http://localhost:8093/query/service -d 'prepared="ejemplo"&args=["bar"]'
Ahora echemos un vistazo de nuevo al registro de auditoría.
tail ~/Library/Application\ Support/Couchbase/var/lib/couchbase/logs/audit.log
El registro mostrará dos eventos, uno para el PREPARE, y otro para el SELECT ejecutado desde la sentencia preparada:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
{ "timestamp": "2018-03-14T06:27:39.884-07:00", "real_userid": { "fuente": "local", "usuario": "Administrador" }, "requestId": "9f76b8c2-ed9f-42f8-bc5c-31fb3326a661", "declaración": "prepare example as select * from test where one=?", "isAdHoc": verdadero, "userAgent": "curl\/7.43.0", "nodo": "127.0.0.1:8091", "status": "éxito", "métricas": { "tiempo transcurrido": "6.591126ms", "executionTime": "6.515079ms", "resultCount": 1, "resultSize": 1279 }, "id": 28674, "nombre": "PREPARATE declaración", "descripción": "Se ejecutó una sentencia N1QL PREPARE" } { "timestamp": "2018-03-14T06:27:52.992-07:00", "real_userid": { "fuente": "interno", "usuario": "desconocido" }, "requestId": "56c5278b-5842-45a9-8549-5c7f52f109a7", "declaración": "", "positionalArgs": [ "\"bar\"" ], "isAdHoc": falso, "userAgent": "curl\/7.43.0", "nodo": "127.0.0.1:8091", "status": "éxito", "métricas": { "tiempo transcurrido": "1.363373ms", "executionTime": "1.334763ms", "resultCount": 0, "resultSize": 0 }, "id": 28672, "nombre": "Declaración SELECT", "descripción": "Se ejecutó una sentencia N1QL SELECT" } |
Los campos de los registros de auditoría son similares a los de la ejecución anterior de una sentencia SELECT, pero cabe destacar dos campos:
- "positionalArgs" contiene el argumento suministrado con la consulta.
- "isAdHoc" es en este caso falso, porque el SELECT se ejecutó desde una sentencia preparada que se envió anteriormente.
Solicitud API
A continuación, vamos a intentar auditar una de las APIs del motor de consultas. Ve a la página de configuración de auditoría, y activa el tipo de evento "/admin/ping API request". No olvides guardar la configuración al final de la página.
Ahora envía un ping:
curl -v http://localhost:8093/admin/ping
No esperes mucho, el "{}" de la parte inferior es todo el resultado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
* Prueba ::1... * Conectado a localhost (::1) puerto 8093 (#0) > GET /admin/ping HTTP/1.1 > Anfitrión: localhost:8093 > Usuario-Agente: rizo/7.43.0 > Acepte: */* > < HTTP/1.1 200 OK < Fecha: Miércoles, 14 Mar 2018 13:54:24 GMT < Contenido-Longitud: 2 < Contenido-Tipo: texto/llano; conjunto de caracteres=utf-8 < * Conexión #0 a host localhost dejado intacto {} |
A continuación, echemos un vistazo al registro de auditoría (de nuevo, utilizando la ubicación en Macs):
tail ~/Library/Application\ Support/Couchbase/var/lib/couchbase/logs/audit.log
El mensaje de registro de auditoría resultante, formateado, tiene el siguiente aspecto:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "timestamp": "2018-03-14T06:54:24.887-07:00", "real_userid": { "fuente": "interno", "usuario": "desconocido" }, "httpMethod": "GET", "httpResultCode": 200, "errorMessage": "", "id": 28697, "nombre": "/admin/ping API request", "descripción": "Se realizó una solicitud HTTP a la API en /admin/ping". } |
Aquí los campos "timestamp" y "real_userid" funcionan como antes, en el ejemplo SELECT. "httpMethod" es el tipo de petición HTTP. "httpResultCode" y "errorMessage" indican lo que ha ocurrido con la solicitud. "Id", "name" y "description" son específicos del evento de auditoría; estos campos serán idénticos para todos los registros de auditoría creados para eventos /admin/ping.
Filtrado hacia delante
(Este es un tema avanzado. No es necesario conocer el material de esta sección para utilizar la auditoría N1QL de forma efectiva. Pero una mirada bajo el capó puede ser de interés para los usuarios avanzados).
La auditoría es controlada en cada servidor por un ejecutable llamado demonio de auditoría. El demonio de auditoría crea todos los registros en el log de auditoría. En 5.0, el demonio de auditoría era responsable de todo el filtrado de eventos; los clientes enviaban registros para todos los eventos auditables, y el demonio de auditoría creaba registros de auditoría en el registro, o no, dependiendo de la configuración de filtrado. Desafortunadamente, esto sería muy ineficiente cuando la auditoría está muy filtrada y los clientes están haciendo mucho trabajo potencialmente auditable. Un cliente como el motor de consultas podría generar millones de registros sólo para que el demonio de auditoría los desechara cuando llegaran.
Para aliviar este problema, en 5.5 Couchbase soporta el filtrado hacia adelante. El motor de consulta es consciente de la configuración de auditoría actual, y envía sólo los registros actualmente auditados al demonio de auditoría. También envía un registro de auditoría especial para indicar que ha recibido la nueva configuración y es consciente de ello.
Este doble filtrado es la razón por la que puede ver dos tipos de registros de configuración en el registro de auditoría. Un registro como este indica que el demonio de auditoría ha recibido una nueva configuración:
1 2 3 4 5 6 7 8 9 10 |
{"tamaño_rotación":20971520,"log_path":"/Users/johanlarson/Library/Application Support/Couchbase/var/lib/couchbase/logs","intervalo_rotación":86400, "disabled_userids":[],"auditd_enabled":verdadero, "desactivado":[20485,20488,20489,20490,20491,28673,28675,28676,28677,28678,28679,28680,28681,28682, 28683,28684,28685,28686,28687,28688,28689,28690,28691,28692,28693,28694,28695,28697,28698,28699, 28700,28701,28702,32770,32771,32772,32780], "enabled:[20480,20482,20483,28672,28674,32768,32769,32773,32774,32775,32776,32777,32778,32779,32781,32782], "real_nombre de usuario":{"fuente":"ns_servidor","usuario":"Administrador"},"sessionid":"8b3d16bffa8444ce596b64a78c0185f7", "remoto":{"ip":"127.0.0.1","puerto":52153}, "marca de tiempo":"2018-03-14T06:25:30.370-07:00","id":8240,"nombre":"configurado auditoría demonio", "descripción":"cargado configuración archivo para auditoría demonio"} |
Y un registro como éste indica que el motor de consulta ha recibido una nueva configuración:
1 2 3 |
{"timestamp":"2018-03-14T06:25:30.427-07:00", "real_userid":{"fuente":"","usuario":""},"uuid":"26571424","id":28703, "nombre":"Configuración N1QL","descripción":"Indica que N1QL está utilizando la configuración de auditoría con el uuid especificado"} |
Observe el UUID que identifica la configuración. Puede obtener este UUID de la configuración, así:
curl http://localhost:8091/pools/default -u Administrador:contraseña
Busque el campo "auditUid".
Puede obtener la configuración de auditoría completa así:
curl http://localhost:8091/settings/audit -u Administrador:contraseña
1 2 3 4 5 6 7 |
{"desactivado":[20485,20488,20489,20490,20491,28673,28675,28676,28677,28678, 28679,28680,28681,28682,28683,28684,28685,28686,28687,28688,28689, 28690,28691,28692,28693,28694,28695,28698,28699,28700,28701,28702, 32770,32771,32772,32780], "uid":"18635804","auditdEnabled":verdadero,"disabledUsers":[], "logPath":"/Users/johanlarson/Library/Application Support/Couchbase/var/lib/couchbase/logs", "rotateInterval":86400,"rotateSize":20971520} |
Carga del registro de auditoría
Couchbase Server actualmente sólo soporta un destino para los registros de auditoría: un archivo en el servidor. Pero a veces sería útil obtener los registros de auditoría en la propia base de datos. Esto no es difícil, ya que los registros de auditoría son JSON. Pero cargar el registro requiere el uso de una utilidad, cbimport.
Suponiendo que tiene el registro de auditoría creado en la ubicación estándar en un Mac, y que ha creado el cubo "test", este encantamiento carga el archivo audit.log en el cubo "test":
/Applications/Couchbase\ Server.app/Contents/Resources/couchbase-core/bin/cbimport json -c http://localhost:8091 -u Administrator -p password -b test -g "#UUID#" -d file:///Users/johanlarson/Library/Application\ Support/Couchbase/var/lib/couchbase/logs/audit.log -f lines
Eso es bastante para tomarlo, y necesitarías variaciones ligeramente diferentes en otros sistemas, así que vamos a ir paso a paso.
- /Applications/Couchbase\ Server.app/Contents/Resources/couchbase-core/bin/cbimport es la ruta completa al comando cbimport en un Mac. Para otros sistemas, las utilidades se encuentran en otro lugar. Véase este documento.
- -c http://localhost:8091 es la URL del servidor donde se ejecuta Couchbase
- -u Administrador -p contraseña es el nombre de usuario y la contraseña del usuario con el que estamos cargando los datos (en este caso el administrador por defecto.)
- -b prueba es el nombre del cubo en el que estamos cargando los datos.
- -g "#UUID#" es el tipo de clave a generar para cada documento introducido en el bucket. En este caso, estamos utilizando un UUID, pero hay muchas otras opciones. Compruebe la cbimport para más información.
- -d file:///Users/johanlarson/Library/Application\ Support/Couchbase/var/lib/couchbase/logs/audit.log es una URL de archivo que apunta a la ubicación del registro de auditoría. Tenga en cuenta las tres barras diagonales y la barra invertida para permitir un espacio en la ruta URL. Los registros, incluido el registro de auditoría, se colocan en directorios estándar que varían de un sistema a otro. Véase este documento para más información.
Una vez que los registros de auditoría están en el sistema, puede consultarlos como cualquier otro dato.Vaya al Query WorkBench para probarlo.
Esta consulta muestra cuántos registros de auditoría tiene:
select count(*) as num from test
Y esta consulta desglosa el recuento por tipo de registro de auditoría:
select nombre, count(*) as num from prueba group by nombre
Resumen
- Las solicitudes al motor de consulta son auditables a partir de Servidor Couchbase 5.5 EE.
- En general, la auditoría admite el filtrado por tipo de evento y la creación de listas blancas de usuarios.
- Las solicitudes se marcan como eventos según el tipo de consulta y el punto final de la API.
- Existe documentación adicional sobre la auditoría de las sentencias N1QL aquí.
- Descargar Couchbase Server 5.5 aquí.
¿Es posible auditar sólo algunos documentos? Por ejemplo, sólo quiero auditar documentos con type='hotels'.
No, no es posible ser selectivo por las características del documento.