¿Qué es una bitácora?
Herramienta que permite registrar, analizar, detectar y notificar eventos que sucedan en cualquier sistema de información utilizado en las organizaciones. La estructura más ampliamente usada para grabar las modificaciones de la base de datos.
Una bitácora permite guardar las transacciones realizadas sobre una base de datos en específico, de tal manera que estas transacciones puedan ser auditadas y analizadas posteriormente.
Pueden obtenerse datos específicos de la transacción como son la Operación que se realizo, el Usuario de BD y Windows, Fecha, Maquina y Programa.
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.
TIPOS DE BITACORA
El sistema guarda diferentes tipos de registros en la bitácora, dependiendo del evento ocurrido en la BD.
Por ejemplo:
Un “registro de actualización” describe una escritura única en la BD y tiene los campos:
- ID_Transacción.
- ID_elemento_datos.
- Valor anterior.
- Valor nuevo.
Otros registros indican eventos especiales como: inicio de transacción, éxito o fracaso de la misma. Una posible vista de la bitácora puede ser:
EJEMPLO EN MYSQL
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.


