jueves, 7 de marzo de 2013

QUE ES UNA BITACORA

BITACORAS DE BASES DE DATOS
 
La estructura más ampliamente usada para grabar las modificaciones de la base de datos es la Bitácora.
Cada registro de la bitácora escribe una única escritura de base de datos y tiene lo siguiente :
  1. Nombre de la transacción : Nombre de la transacción que realizó la operación de escritura.
  2. Nombre del dato : El nombre único del dato escrito.
  3. Valor antiguo : El valor del dato antes de la escritura.
  4. Valor nuevo : El valor que tendrá el dato después de  la escritura.
Existen otros registros de bitácora especiales para grabar sucesos importantes durante el proceso de transacción tales como :
< T1, inicio >
< T1, x, v1, v2 >
< T1, commit >
Es fundamental que siempre se cree un registro en la bitácora cuando se realice una escritura antes de que se modifique la base de datos.
También tenemos la posibilidad de deshacer una modificación que ya se ha escrito en la base de datos, esto se realizará usando el campo del valor antiguo de los registros de la bitácora.
Los registros de la bitácora deben residir en memoria estable como resultado el volumen de datos en la bitácora puede ser exageradamente grande.
 
 
Crear una bitácora en MySQL
 
La importancia de las bitácoras es la de recuperar información ante incidentes de seguridad, detección de comportamiento inusual, información para resolver problemas, evidencia legal, es de gran ayuda en las tareas de cómputo forense.
Enseguida plantearé un ejemplo de una bitácora desarrollada para la siguiente base de datos de MySQL, llamada proyecto, que tiene las tablas carrera, departamento y maestros.
CREATE DATABASE proyecto;
USE proyecto
CREATE TABLE IF NOT EXISTS `carrera` (`clave_carrera` int(11) NOT NULL, `nom_carrera` varchar(20) NOT NULL, `num_depto` int(11) NOT NULL, PRIMARY KEY (`clave_carrera`), KEY `num_depto` (`num_depto`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `departamento` ( `num_departamento` int(11) NOT NULL,`nombre_dept` varchar(20) NOT NULL, `jefe_num_tarjet` int(11) NOT NULL, PRIMARY KEY (`num_departamento`), KEY `jefe_num_tarjet` (`jefe_num_tarjet`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `maestros` (`num_tarjeta` int(11) NOT NULL DEFAULT ’0′,`nombre` varchar(50) DEFAULT NULL, PRIMARY KEY (`num_tarjeta`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
La estructura de la tabla bitácora sería la siguiente:
CREATE TABLE IF NOT EXISTS `bitacora` (`id` int(11) NOT NULL AUTO_INCREMENT, `operacion` varchar(10) DEFAULT NULL, `usuario` varchar(40) DEFAULT NULL, `host` varchar(30) NOT NULL, `modificado` datetime DEFAULT NULL, `tabla` varchar(40) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
La bitácora debe registrar todos los movimientos (insertar, eliminar y modificar) que se realicen en las tablas de la base de datos. Para lograr lo anterior es necesario crear un trigger para que se ejecute después de la operación de insertar, otro para después de eliminar y el último para después de modificar para cada una de las 3 tablas de la base de datos. Los nueve triggers necesarios para que funcione la bitácora son los siguientes:
DROP TRIGGER IF EXISTS `bit_carr_ins`;
DELIMITER //
CREATE TRIGGER `bitacora` AFTER INSERT ON `carrera`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “INSERTAR”, NOW(), “CARRERA”)
//
DROP TRIGGER IF EXISTS `bit_carr_upd`;
CREATE TRIGGER `bit_carr_upd` AFTER UPDATE ON `carrera`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “ACTUALIZAR”, NOW(), “CARRERA”)
//

DROP TRIGGER IF EXISTS `bit_carr_del`;
CREATE TRIGGER `bit_carr_del` AFTER DELETE ON `carrera`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “ELIMINAR”, NOW(), “CARRERA”)
//

DROP TRIGGER IF EXISTS `bit_depto_ins`;
CREATE TRIGGER `bit_depto_ins` AFTER INSERT ON `departamento`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “INSERTAR”, NOW(), “DEPARTAMENTO”)
//
DROP TRIGGER IF EXISTS `bit_depto_upd`;
CREATE TRIGGER `bit_depto_upd` AFTER UPDATE ON `departamento`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “ACTUALIZAR”, NOW(), “DEPARTAMENTO”)
//

DROP TRIGGER IF EXISTS `bit_depto_del`;
CREATE TRIGGER `bit_depto_del` AFTER DELETE ON `departamento`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “ELIMINAR”, NOW(), “DEPARTAMENTO”)
//

DROP TRIGGER IF EXISTS `bit_mae_ins`;
CREATE TRIGGER `bit_mae_ins` AFTER INSERT ON `maestros`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “INSERTAR”, NOW(), “MAESTROS”)
//
DROP TRIGGER IF EXISTS `bit_mae_upd`;
CREATE TRIGGER `bit_mae_upd` AFTER UPDATE ON `maestros`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “ACTUALIZAR”, NOW(), “MAESTROS”)
//

DROP TRIGGER IF EXISTS `bit_mae_del`;
CREATE TRIGGER `bit_mae_del` AFTER DELETE ON `maestros`
FOR EACH ROW INSERT INTO bitacora(host, usuario, operacion, modificado, tabla) VALUES (SUBSTRING(USER(), (INSTR(USER(),’@')+1)), SUBSTRING(USER(),1,(instr(user(),’@')-1)), “ELIMINAR”, NOW(), “MAESTROS”)
//

El resultado que se espera de la bitácora se muestra en la siguiente imagen.
Resultado de la bitacora
 
 
Cómo activar la auditoría de una base de datos Oracle
 
Se pretende mediante un sencillo ejemplo práctico para ver cómo se puede auditar las conexiónes a una base de datos ORACLE o auditar los intentos de modificación a las tablas de un usuario.
Teniendo en cuenta que el parámetro que habilita la posibilidad de auditar la base de datos ORACLE en el init.ora es audit_trail que el comando sql que activa la auditoría sobre algo es AUDIT ( para desactivar NOAUDIT ) y que la tabla para mirar ( usuario sys ) el seguimiento de auditoría es dba_audit_trail vamos a realizar este sencillo ejemplo.
  1. Activar la auditoria de intento de conexiones fallidas para todos los usuarios.
    Miramos que actualmente no está activada la auditoria en la base de datos
    SQL> select name , value from v$parameter where name like ‘audit_trail’;
    audit_trail NONE
    Activamos la auditoría de la base de datos
    SQL> alter system set audit_trail = DB scope = spfile;
    Reiniciamos la base de datos ( shutdown immediate, startup ) y comprobamos que la auditoría se ha activado.
    SQL> select name , value from v$parameter where name like ‘audit_trail’;
    audit_trail DB
    Activamos la auditoría para ver la conexión y desconexión de los usuarios a la base de datos, se hace con la siguiente sentencia
    SQL> audit connect;

  2. Visualizar las tablas de auditoría para comprobar que se insertan datos cuando intentamos conectarnos sin lograrlo.
    En el apartado anterior hemos activado la auditoría para ver como se conectan los usuarios a la base de datos, vamos a realizar varias pruebas y mostrar dónde se puede comprobar que los usuarios se han conectado a la base de datos.
    Nos conectamos con varios usuarios a la base de datos ( en nuestro caso con system y el usuario user9 que está creado )
    SQL> connect user9/user9;
    SQL> connect system/system;
    Tras habernos conectado a la base de datos miramos la tabla dba_audit_trail para ver que datos contiene.
    SQL> select username , action_name , priv_used , returncode from dba_audit_trail ;
    “SYSTEM” “LOGON” 1017
    “SYSTEM” “LOGON” 1017
    “USER9″ “LOGON” 1017
    “USER9″ “LOGON” “CREATE SESSION” 0
    “USER9″ “LOGON” 1017
    “USER9″ “LOGON” 1017
    Observarmos que en esta tabla se registran los intentos de conexión de los usuarios, por lo tanto podemos saber quien se ha conectado a la base de datos

  3. Activar la auditoria sobre la modificación de tablas del usuario Scott.
    Ahora vamos a activar la auditoría sobre la modificación de las tablas sobre el usuario Scott, de esta forma cualquier modificación realizada en una tabla que pertenezca a este usuario será registrada en las tablas y podremos ver quien ha realizado esa modifiación.
    SQL>audit insert,update on scott . bonus by access;
    SQL>audit insert,update on scott . emp by access;
    SQL>audit insert,update on scott .dept by access;
    SQL>audit insert,update on scott . salgrade by access;
    En este caso estamos auditando cada una de las tablas que pertenencen al usuario scott ( bonus, emp, dept, salgrade ) en caso de que alguien inserte algo en ellas o realice alguna actualización. ( si queremos auditar el borrado o la lectura de alguna fila, solo hay que añadir los permisos de select y delete detrás del comando audit).Al ponerlo by access se guardará un registro en la tabla de auditoría por cada intento de insert o update que se realice sobre cada una de las tablas nombradas. ( exite también el registro by session, en el cual se registra por sesión única el intento de insert o update sobre las tablas ).
    Miramos la tabla user_obj_audit_opts ( con el usuario scott )
    SQL>select * from user_obj_audit_opts;
    “BONUS” “TABLE” “-/-” “-/-” “-/-” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “-/-” “-/-”
    “DEPT” “TABLE” “-/-” “-/-” “-/-” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “-/-” “-/-”
    “EMP” “TABLE” “-/-” “-/-” “-/-” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “-/-” “-/-”
    “SALGRADE” “TABLE” “-/-” “-/-” “-/-” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “A/A” “-/-” “-/-” “-/-” “-/-” “-/-”
    Y observamos que es lo que estamos auditando del usuario scott, en este caso se vería que eta activada para cada una de las tablas la auditoría para update e insert.
    (A/A) –> activado / por acceso
    La prueba que se puede realizar es conectarse con otro usuario que tenga permisos de insert y update sobre estas tablas y realizar una serie de inserciones y actualizaciones en esas tablas. En este caso suponemos que un usuario, user9 que tiene permisos de inserción y actualización sobre las tablas del usuario scott ha realizado una serie de inserciones y actualizaciones sobre estas tablas. La forma de ver si las ha realizado o no ( teniendo activada la auditoría es la siguiente ).
    SQL>select * from sys . dba_audit_trail where ( action_name = ‘INSERT’ ) or ( action_name = ‘UPDATE’ ) ;
    El resultado es el siguiente:
    “ERIN-0S2WXM4BDG\Erin” “USER9″ “ERIN-0S2WXM4BDG” 19/04/2006 15:38:56 “SCOTT” “BONUS” 2 “INSERT” 267 2 47 0
    “ERIN-0S2WXM4BDG\Erin” “USER9″ “ERIN-0S2WXM4BDG” 19/04/2006 15:39:09 “SCOTT” “BONUS” 2 “INSERT” 267 3 50 0
    “ERIN-0S2WXM4BDG\Erin” “USER9″ “ERIN-0S2WXM4BDG” 19/04/2006 15:39:19 “SCOTT” “BONUS” 6 “UPDATE” 267 4 55 0
    Observamos que se han registrado los intentos de inserción y de modificación sobre la tabla BONUS.
 
 
 
 

2 comentarios: