DBaudit es una plataforma de auditoría de bases de datos distribuida. Su objetivo es monitorear y registrar eventos (INSERT, UPDATE, DELETE, DDL, etc.) que ocurren en bases de datos locales o en servidores remotos, incluso si están en redes aisladas sin acceso directo.
En entornos empresariales con múltiples bases de datos distribuidas en distintos servidores, llevar un registro centralizado de quién hizo qué, cuándo y sobre qué tabla es un requisito crítico de seguridad y cumplimiento normativo (GDPR, SOX, HIPAA).
┌─────────────────────┐ HTTPS / HTTP ┌──────────────────────────┐
│ Servidor remoto │ ──────────────────────────► │ Servidor central │
│ │ │ │
│ ┌───────────────┐ │ │ ┌────────────────────┐ │
│ │ Base de datos│ │ │ │ Backend Django │ │
│ │ PostgreSQL / │ │ │ │ (REST API) │ │
│ │ MySQL / etc. │ │ │ └────────────────────┘ │
│ └──────┬────────┘ │ │ │
│ │ triggers │ │ ┌────────────────────┐ │
│ ┌──────▼────────┐ │ │ │ Frontend React │ │
│ │ audit_log │ │ │ │ (Dashboard) │ │
│ └──────┬────────┘ │ │ └────────────────────┘ │
│ │ │ │ │
│ ┌──────▼────────┐ │ │ ┌────────────────────┐ │
│ │ dbaudit-agent │──┼───────────────────────────► │ │ Base de datos │ │
│ │ (Python) │ │ POST /api/ingest/events/ │ │ central │ │
│ └───────────────┘ │ │ └────────────────────┘ │
└─────────────────────┘ └──────────────────────────┘
Componentes:
- Agente Python (
dbaudit-agent.py): Se instala en cada servidor con base de datos. Lee eventos mediante triggers, los almacena en una cola local SQLite (tolerancia a fallos) y los envía al backend central por HTTP. - Backend Django: Recibe, valida y almacena eventos. Expone una REST API consumida por el frontend. Incluye motor de alertas configurable.
- Frontend React + Vite: Dashboard centralizado con visualización de agentes, bases de datos, eventos de auditoría, alertas y reportes de cumplimiento.
| Componente | Versión mínima |
|---|---|
| Python | 3.8+ (recomendado 3.12) |
| Node.js | 18+ |
| npm | 9+ |
| PostgreSQL | 15+ |
| MySQL | 8+ (si se usa MySQL) |
| Git | cualquier versión reciente |
Actualizar pip antes de comenzar:
pip install --upgrade pipgit clone https://github.com/tu-usuario/dbaudit.git
cd dbauditpython -m venv venv
# Linux / Mac
source venv/bin/activate
# Windows PowerShell
venv\Scripts\activatepip install -r requirements.txtCrea un archivo .env en la carpeta backend/:
SECRET_KEY=tu_clave_secreta_django
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
DATABASE_URL=postgresql://usuario:password@localhost:5432/dbaudit_dbcd backend
python manage.py migrate
python manage.py createsuperuserpython manage.py runserverEl backend estará disponible en http://localhost:8000.
cd frontend
npm installLas dependencias principales incluyen:
npm install recharts lucide-reactCrea un archivo .env en la carpeta frontend/:
VITE_API_URL=http://localhost:8000/apinpm run devEl frontend estará disponible en http://localhost:5173.
El agente es el componente que se instala en cada servidor con base de datos. Soporta múltiples instancias simultáneas, una por cada base de datos a auditar, cada una con su propia cola y logs independientes.
Se crea un archivo .env por cada base de datos a monitorear. En Windows, estos archivos deben ubicarse en:
C:\Users\<usuario>\AppData\Local\DBaudit\
En Linux, se ubican en:
/etc/dbaudit/
Ejemplo de configuración (agent_nombre_bd.env):
AUDIT_SERVER_URL=http://IP_DEL_SERVIDOR_CENTRAL:8000
AGENT_TOKEN=token_generado_desde_el_dashboard
AGENT_ID=uuid_generado_desde_el_dashboard
DB_ENGINE=postgresql
DB_HOST=localhost
DB_PORT=5432
DB_NAME=nombre_de_la_bd
DB_USER=postgres
DB_PASSWORD=tu_password
POLL_INTERVAL=15
BATCH_SIZE=100
RETRY_INTERVAL=30
MAX_QUEUE_SIZE=10000
LOG_LEVEL=INFO
VERIFY_SSL=false
⚠️ Importante: ElAGENT_TOKENy elAGENT_IDse obtienen al registrar el agente desde el dashboard de DBaudit (ver sección 7).
Motores soportados y sus puertos por defecto:
| Motor | DB_ENGINE |
Puerto por defecto |
|---|---|---|
| PostgreSQL | postgresql |
5432 |
| MySQL / MariaDB | mysql |
3306 |
| SQL Server | mssql |
1433 |
| Oracle | oracle |
1521 |
| SQLite | sqlite |
0 |
Cada agente se ejecuta en su propia terminal. El nombre del archivo .env se pasa como variable de entorno AGENT_ENV:
Windows (PowerShell):
# Terminal 1 — Base de datos 1
$env:AGENT_ENV="agent_bd_1.env"
python dbaudit-agent.py --run
# Terminal 2 — Base de datos 2
$env:AGENT_ENV="agent_bd_2.env"
python dbaudit-agent.py --runLinux / Mac:
# Terminal 1 — Base de datos 1
export AGENT_ENV="agent_bd_1.env"
python3 dbaudit-agent.py --run
# Terminal 2 — Base de datos 2
export AGENT_ENV="agent_bd_2.env"
python3 dbaudit-agent.py --runEl agente crea archivos independientes por cada instancia, aislando las colas y los logs:
Windows:
AppData\Local\DBaudit\
├── agent_bd_1.env
├── agent_bd_2.env
├── queue_agent_bd_1.db ← cola local SQLite (agente 1)
├── queue_agent_bd_2.db ← cola local SQLite (agente 2)
└── logs\
├── agent_bd_1.log
└── agent_bd_2.log
Linux:
/var/lib/dbaudit/
├── queue_agent_bd_1.db
├── queue_agent_bd_2.db
/var/log/
├── dbaudit-agent_bd_1.log
└── dbaudit-agent_bd_2.log
La cola local SQLite garantiza que los eventos no se pierdan si el servidor central no está disponible temporalmente. El agente los reintenta automáticamente al reconectarse.
- Inicia sesión en el dashboard de DBaudit.
- Ve a la sección Agentes → Registrar Agente.
- Completa el nombre del agente y la IP del servidor donde se instalará.
- El sistema genera automáticamente un
AGENT_TOKENy unAGENT_ID. - Copia esos valores y agrégalos al archivo
.envdel agente correspondiente. - Desde la tarjeta del agente en el dashboard, usa el botón "Ver Script" para obtener el comando de instalación completo listo para copiar y pegar.
Esta sección cubre la instalación del agente en un servidor Linux al que se tiene acceso por SSH (por ejemplo desde PuTTY).
python3 --versionSi la versión es inferior a 3.8, instalar una versión más reciente:
# Debian / Ubuntu
sudo apt update && sudo apt install python3.11 python3.11-venv -y
# CentOS / RHEL / Oracle Linux
sudo dnf install python3.11 -y
# CentOS 7 (versión antigua)
sudo yum install python38 -ysudo mkdir -p /etc/dbaudit /var/lib/dbaudit /var/log/dbauditcd /etc/dbaudit
python3 -m venv venv
source venv/bin/activateInstalar la librería según el motor de base de datos:
# PostgreSQL
pip install psycopg2-binary requests
# MySQL / MariaDB
pip install pymysql requests
# Oracle
pip install cx_Oracle requests
# SQL Server
pip install pyodbc requestsOpción A — desde tu PC con scp:
scp dbaudit-agent.py usuario@192.168.37.215:/etc/dbaudit/Opción B — directamente desde PuTTY:
nano /etc/dbaudit/dbaudit-agent.py
# Pegar el contenido del archivo y guardar con Ctrl+O, salir con Ctrl+Xnano /etc/dbaudit/agent_nombre_bd.envContenido (ajustar según la BD):
AUDIT_SERVER_URL=http://IP_DE_TU_PC_CENTRAL:8000
AGENT_TOKEN=token_del_dashboard
AGENT_ID=uuid_del_dashboard
DB_ENGINE=postgresql
DB_HOST=localhost
DB_PORT=5432
DB_NAME=nombre_bd
DB_USER=postgres
DB_PASSWORD=tu_password
POLL_INTERVAL=30
BATCH_SIZE=100
RETRY_INTERVAL=60
MAX_QUEUE_SIZE=10000
LOG_LEVEL=INFO
VERIFY_SSL=falseAntes de ejecutar el agente, confirma que el servidor Linux puede alcanzar el servidor central:
curl http://IP_DE_TU_PC_CENTRAL:8000/api/agents/Si hay respuesta JSON, la conexión está bien. Si no responde, revisar el firewall del servidor central (puerto 8000).
cd /etc/dbaudit
source venv/bin/activate
export AGENT_ENV="agent_nombre_bd.env"
python3 dbaudit-agent.py --runPara que el agente arranque automáticamente con el servidor:
sudo nano /etc/systemd/system/dbaudit-agent.service[Unit]
Description=DBaudit Agent
After=network.target postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=/etc/dbaudit
Environment=AGENT_ENV=agent_nombre_bd.env
ExecStart=/etc/dbaudit/venv/bin/python3 /etc/dbaudit/dbaudit-agent.py --run
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable dbaudit-agent
sudo systemctl start dbaudit-agent
# Verificar estado
sudo systemctl status dbaudit-agent
# Ver logs en tiempo real
journalctl -u dbaudit-agent -fEl agente lee eventos desde la tabla dbaudit.audit_log, que se llena mediante triggers en las tablas que se desean auditar.
Recomendación: No auditar todas las tablas. Seleccionar únicamente las tablas con datos sensibles o críticos para el negocio (pagos, usuarios, roles, inventario, etc.). Crear un trigger individual por tabla permite controlar exactamente qué operaciones auditar en cada una.
Ejecutar en pgAdmin o psql conectado a la BD destino:
CREATE SCHEMA IF NOT EXISTS dbaudit;
CREATE TABLE IF NOT EXISTS dbaudit.audit_log (
id BIGSERIAL PRIMARY KEY,
table_name TEXT,
operation TEXT,
db_user TEXT,
client_host TEXT,
occurred_at TIMESTAMPTZ DEFAULT NOW(),
old_data JSONB,
new_data JSONB,
sent BOOLEAN DEFAULT FALSE
);CREATE OR REPLACE FUNCTION dbaudit.log_changes()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO dbaudit.audit_log (
table_name, operation, db_user, client_host, old_data, new_data
)
VALUES (
TG_TABLE_NAME,
TG_OP,
current_user,
inet_client_addr()::text,
CASE WHEN TG_OP = 'DELETE' THEN row_to_json(OLD)::jsonb ELSE NULL END,
CASE WHEN TG_OP != 'DELETE' THEN row_to_json(NEW)::jsonb ELSE NULL END
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;-- Reemplazar "public.nombre_tabla" con la tabla que se quiere auditar
CREATE TRIGGER audit_nombre_tabla
AFTER INSERT OR UPDATE OR DELETE ON public.nombre_tabla
FOR EACH ROW EXECUTE FUNCTION dbaudit.log_changes();Repetir este paso por cada tabla que se desee auditar. Todos los eventos quedan en la misma tabla dbaudit.audit_log, diferenciados por el campo table_name.
| Componente | Comando |
|---|---|
| Backend | python manage.py runserver |
| Frontend | npm run dev |
| Agente (Windows) | $env:AGENT_ENV="agent.env"; python dbaudit-agent.py --run |
| Agente (Linux) | export AGENT_ENV="agent.env" && python3 dbaudit-agent.py --run |
| Componente | Tecnología recomendada |
|---|---|
| Backend | Gunicorn + Nginx |
| Frontend | npm run build → servir estático con Nginx |
| Agente | Servicio systemd (ver sección 8.8) |
| Base de datos central | PostgreSQL con backups automáticos |
PROYECTO_DBAUDIT/
├── backend/
│ ├── audit/
│ │ ├── migrations/
│ │ ├── admin.py
│ │ ├── alert_engine.py
│ │ ├── apps.py
│ │ ├── ingest.py
│ │ ├── models.py
│ │ ├── permissions.py
│ │ ├── serializers.py
│ │ ├── urls.py
│ │ └── views.py
│ ├── dbaudit_project/
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ └── manage.py
├── frontend/
│ ├── src/
│ │ ├── App.jsx
│ │ ├── api.js
│ │ ├── constants.js
│ │ ├── mockData.js
│ │ ├── ui.jsx
│ │ ├── Dashboard.jsx
│ │ ├── AgentsView.jsx
│ │ ├── EventsView.jsx
│ │ ├── AlertsView.jsx
│ │ ├── DatabasesView.jsx
│ │ └── ReportsView.jsx
│ ├── package.json
│ └── vite.config.js
├── dbaudit-agent.py
├── extend_audit_schema.sql
├── requirements.txt
├── README.md
└── .gitignore
| Recurso | Método | Endpoint |
|---|---|---|
| Agentes | GET / POST | /api/agents/ |
| Agente por ID | GET / PATCH / DELETE | /api/agents/{id}/ |
| Bases de datos | GET / POST | /api/databases/ |
| Base de datos por ID | GET / PUT / DELETE | /api/databases/{id}/ |
| Eventos de auditoría | GET | /api/events/ |
| Alertas | GET / PATCH | /api/alerts/ |
| Reglas de alerta | GET / POST | /api/alert-rules/ |
| Ingest de eventos (agente) | POST | /api/ingest/events/ |
| Heartbeat (agente) | POST | /api/ingest/heartbeat/ |
| Config del agente | GET | /api/ingest/config/ |
Para simular carga y verificar que el agente maneja correctamente grandes volúmenes de eventos:
# simulador.py — ejecutar con el venv activado
import psycopg2, random
NOMBRES = ["Laptop", "Mouse", "Teclado", "Monitor", "Auriculares"]
MARCAS = ["Samsung", "Logitech", "HP", "Dell", "Sony"]
conn = psycopg2.connect(host="localhost", dbname="nombre_bd", user="postgres", password="password")
cur = conn.cursor()
for i in range(1000):
nombre = f"{random.choice(MARCAS)} {random.choice(NOMBRES)}"
precio = round(random.uniform(10, 2000), 2)
cur.execute("INSERT INTO productos (nombre, precio) VALUES (%s, %s)", (nombre, precio))
conn.commit()
cur.close()
conn.close()
print("✅ 1000 productos insertados")Con BATCH_SIZE=100 y POLL_INTERVAL=15, el agente procesa ~400 eventos/minuto. Para mayor throughput ajustar en el .env:
BATCH_SIZE=500
POLL_INTERVAL=10El agente no envía eventos:
- Verificar que el
AGENT_TOKENen el.envcorresponde al agente registrado en el dashboard. - Confirmar que el servidor central es accesible:
curl http://IP_SERVIDOR:8000/api/agents/ - Revisar que el trigger está creado en la tabla correcta y que
dbaudit.audit_logrecibe registros.
Dos agentes comparten la misma cola:
- Verificar que cada agente usa un archivo
.envdistinto con nombre diferente. - La cola se nombra automáticamente según el
.env:queue_agent_nombre.db.
La IP del cliente muestra ::1 en lugar de 127.0.0.1:
- Es el equivalente IPv6 de localhost. Es correcto y esperado en conexiones locales.
- Para forzar IPv4 cambiar
DB_HOST=127.0.0.1en lugar delocalhost.
Error ModuleNotFoundError: No module named 'psycopg2':
- El script no se está ejecutando dentro del entorno virtual.
- Activar el venv antes de ejecutar:
source venv/bin/activate(Linux) ovenv\Scripts\activate(Windows).
Proyecto desarrollado por Alex Muñoz.
MIT License