Initial commit: MSP Monitor Dashboard

- Next.js 14 frontend with dark cyan/navy theme
- tRPC API with Prisma ORM
- MeshCentral, LibreNMS, Headwind MDM integrations
- Multi-tenant architecture
- Alert system with email/SMS/webhook notifications
- Docker Compose deployment
- Complete documentation
This commit is contained in:
MSP Monitor
2026-01-21 19:29:20 +00:00
commit f4491757d9
57 changed files with 10503 additions and 0 deletions

516
docs/api/README.md Normal file
View File

@@ -0,0 +1,516 @@
# API Reference
## Vision General
La API de MSP Monitor Dashboard utiliza [tRPC](https://trpc.io/) para comunicacion type-safe entre frontend y backend. Todos los endpoints estan disponibles bajo `/api/trpc`.
## Autenticacion
### Login con Email/Password
```typescript
// POST /api/trpc/auth.login
const result = await trpc.auth.login.mutate({
email: "usuario@example.com",
password: "password123"
})
// Returns: { success: true, user: { id, email, nombre, rol } }
```
### Login con MeshCentral SSO
```typescript
// POST /api/trpc/auth.loginMeshCentral
const result = await trpc.auth.loginMeshCentral.mutate({
username: "meshuser",
token: "mesh-auth-token"
})
```
### Logout
```typescript
// POST /api/trpc/auth.logout
await trpc.auth.logout.mutate()
```
### Usuario Actual
```typescript
// GET /api/trpc/auth.me
const user = await trpc.auth.me.query()
// Returns: { id, email, nombre, rol, cliente, permisos }
```
## Clientes (Tenants)
### Listar Clientes
```typescript
// GET /api/trpc/clientes.list
const { clientes, pagination } = await trpc.clientes.list.query({
search: "term",
activo: true,
page: 1,
limit: 20
})
```
### Obtener Cliente
```typescript
// GET /api/trpc/clientes.byId
const cliente = await trpc.clientes.byId.query({ id: "client-id" })
```
### Crear Cliente
```typescript
// POST /api/trpc/clientes.create
const cliente = await trpc.clientes.create.mutate({
nombre: "Empresa XYZ",
codigo: "XYZ",
email: "contacto@xyz.com",
meshcentralGrupo: "mesh-group-id"
})
```
### Estadisticas del Dashboard
```typescript
// GET /api/trpc/clientes.dashboardStats
const stats = await trpc.clientes.dashboardStats.query({
clienteId: "optional-client-id"
})
// Returns: {
// totalDispositivos, dispositivosOnline, dispositivosOffline,
// dispositivosAlerta, alertasActivas, alertasCriticas
// }
```
## Equipos (PC/Laptop/Servidor)
### Listar Equipos
```typescript
// GET /api/trpc/equipos.list
const { dispositivos, pagination } = await trpc.equipos.list.query({
clienteId: "client-id",
tipo: "SERVIDOR", // PC | LAPTOP | SERVIDOR
estado: "ONLINE", // ONLINE | OFFLINE | ALERTA | MANTENIMIENTO
search: "term",
page: 1,
limit: 20
})
```
### Obtener Equipo
```typescript
// GET /api/trpc/equipos.byId
const equipo = await trpc.equipos.byId.query({ id: "device-id" })
// Incluye: cliente, ubicacion, software, alertas activas
```
### Obtener Metricas
```typescript
// GET /api/trpc/equipos.metricas
const metricas = await trpc.equipos.metricas.query({
dispositivoId: "device-id",
periodo: "24h" // 1h | 6h | 24h | 7d | 30d
})
```
### Iniciar Sesion Remota
```typescript
// POST /api/trpc/equipos.iniciarSesion
const { sesionId, url } = await trpc.equipos.iniciarSesion.mutate({
dispositivoId: "device-id",
tipo: "desktop" // desktop | terminal | files
})
// Redirigir a `url` para abrir conexion
```
### Ejecutar Comando
```typescript
// POST /api/trpc/equipos.ejecutarComando
const resultado = await trpc.equipos.ejecutarComando.mutate({
dispositivoId: "device-id",
comando: "Get-Process",
tipo: "powershell" // powershell | cmd | bash
})
// Returns: { success: true, output: "..." }
```
### Reiniciar/Apagar
```typescript
// POST /api/trpc/equipos.reiniciar
await trpc.equipos.reiniciar.mutate({ dispositivoId: "device-id" })
// POST /api/trpc/equipos.apagar
await trpc.equipos.apagar.mutate({ dispositivoId: "device-id" })
```
## Celulares (MDM)
### Listar Celulares
```typescript
// GET /api/trpc/celulares.list
const { dispositivos, pagination } = await trpc.celulares.list.query({
clienteId: "client-id",
estado: "ONLINE",
search: "term"
})
```
### Obtener Ubicacion
```typescript
// GET /api/trpc/celulares.ubicacion
const { lat, lng, updatedAt } = await trpc.celulares.ubicacion.query({
dispositivoId: "device-id"
})
```
### Solicitar Ubicacion
```typescript
// POST /api/trpc/celulares.solicitarUbicacion
await trpc.celulares.solicitarUbicacion.mutate({
dispositivoId: "device-id"
})
```
### Bloquear/Desbloquear
```typescript
// POST /api/trpc/celulares.bloquear
await trpc.celulares.bloquear.mutate({
dispositivoId: "device-id",
mensaje: "Dispositivo bloqueado por seguridad"
})
// POST /api/trpc/celulares.desbloquear
await trpc.celulares.desbloquear.mutate({
dispositivoId: "device-id"
})
```
### Hacer Sonar
```typescript
// POST /api/trpc/celulares.sonar
await trpc.celulares.sonar.mutate({
dispositivoId: "device-id"
})
```
### Enviar Mensaje
```typescript
// POST /api/trpc/celulares.enviarMensaje
await trpc.celulares.enviarMensaje.mutate({
dispositivoId: "device-id",
mensaje: "Mensaje para el usuario"
})
```
### Borrar Datos (Factory Reset)
```typescript
// POST /api/trpc/celulares.borrarDatos
// CUIDADO: Esta accion es irreversible
await trpc.celulares.borrarDatos.mutate({
dispositivoId: "device-id"
})
```
### Instalar/Desinstalar App
```typescript
// POST /api/trpc/celulares.instalarApp
await trpc.celulares.instalarApp.mutate({
dispositivoId: "device-id",
packageName: "com.example.app"
})
// POST /api/trpc/celulares.desinstalarApp
await trpc.celulares.desinstalarApp.mutate({
dispositivoId: "device-id",
packageName: "com.example.app"
})
```
## Red (SNMP/NetFlow)
### Listar Dispositivos de Red
```typescript
// GET /api/trpc/red.list
const { dispositivos, pagination } = await trpc.red.list.query({
clienteId: "client-id",
tipo: "ROUTER", // ROUTER | SWITCH | FIREWALL | AP | IMPRESORA | OTRO
estado: "ONLINE"
})
```
### Obtener Interfaces
```typescript
// GET /api/trpc/red.interfaces
const interfaces = await trpc.red.interfaces.query({
dispositivoId: "device-id"
})
// Returns: [{ ifName, ifAlias, ifSpeed, ifOperStatus, ifInOctets_rate, ifOutOctets_rate }]
```
### Obtener Trafico
```typescript
// GET /api/trpc/red.trafico
const datos = await trpc.red.trafico.query({
dispositivoId: "device-id",
portId: 123,
periodo: "24h"
})
// Returns: [{ timestamp, in, out }]
```
### Obtener Topologia
```typescript
// GET /api/trpc/red.topologia
const { nodes, links } = await trpc.red.topologia.query({
clienteId: "client-id"
})
// Para visualizacion con D3.js o similar
```
## Alertas
### Listar Alertas
```typescript
// GET /api/trpc/alertas.list
const { alertas, pagination } = await trpc.alertas.list.query({
clienteId: "client-id",
estado: "ACTIVA", // ACTIVA | RECONOCIDA | RESUELTA
severidad: "CRITICAL", // INFO | WARNING | CRITICAL
dispositivoId: "device-id",
desde: new Date("2024-01-01"),
hasta: new Date("2024-01-31")
})
```
### Reconocer Alerta
```typescript
// POST /api/trpc/alertas.reconocer
await trpc.alertas.reconocer.mutate({ id: "alert-id" })
```
### Resolver Alerta
```typescript
// POST /api/trpc/alertas.resolver
await trpc.alertas.resolver.mutate({ id: "alert-id" })
```
### Conteo de Alertas Activas
```typescript
// GET /api/trpc/alertas.conteoActivas
const { total, critical, warning, info } = await trpc.alertas.conteoActivas.query({
clienteId: "client-id"
})
```
## Reglas de Alerta
### Listar Reglas
```typescript
// GET /api/trpc/alertas.reglas.list
const reglas = await trpc.alertas.reglas.list.query({
clienteId: "client-id"
})
```
### Crear Regla
```typescript
// POST /api/trpc/alertas.reglas.create
const regla = await trpc.alertas.reglas.create.mutate({
clienteId: "client-id", // null para regla global
nombre: "CPU Alta",
metrica: "cpu",
operador: ">",
umbral: 90,
duracionMinutos: 5,
severidad: "WARNING",
notificarEmail: true,
notificarSms: false
})
```
## Reportes
### Reporte de Inventario
```typescript
// GET /api/trpc/reportes.inventario
const { dispositivos, resumen } = await trpc.reportes.inventario.query({
clienteId: "client-id",
tipo: "SERVIDOR"
})
```
### Reporte de Uptime
```typescript
// GET /api/trpc/reportes.uptime
const { dispositivos, promedioGeneral } = await trpc.reportes.uptime.query({
clienteId: "client-id",
desde: new Date("2024-01-01"),
hasta: new Date("2024-01-31")
})
```
### Reporte de Alertas
```typescript
// GET /api/trpc/reportes.alertas
const { alertas, resumen } = await trpc.reportes.alertas.query({
clienteId: "client-id",
desde: new Date("2024-01-01"),
hasta: new Date("2024-01-31")
})
```
### Exportar a CSV
```typescript
// POST /api/trpc/reportes.exportarCSV
const { filename, content, contentType } = await trpc.reportes.exportarCSV.mutate({
tipo: "inventario", // inventario | alertas | actividad
clienteId: "client-id"
})
// Descargar el contenido como archivo CSV
```
## Usuarios
### Listar Usuarios
```typescript
// GET /api/trpc/usuarios.list
const { usuarios, pagination } = await trpc.usuarios.list.query({
clienteId: "client-id",
rol: "TECNICO",
activo: true
})
```
### Crear Usuario
```typescript
// POST /api/trpc/usuarios.create
const usuario = await trpc.usuarios.create.mutate({
email: "nuevo@example.com",
nombre: "Nuevo Usuario",
password: "password123",
clienteId: "client-id",
rol: "TECNICO"
})
```
### Resetear Password
```typescript
// POST /api/trpc/usuarios.resetPassword
await trpc.usuarios.resetPassword.mutate({
id: "user-id",
newPassword: "newpassword123"
})
```
## Configuracion
### Obtener Configuracion
```typescript
// GET /api/trpc/configuracion.get
const config = await trpc.configuracion.get.query({
clave: "smtp_host"
})
```
### Establecer Configuracion
```typescript
// POST /api/trpc/configuracion.set
await trpc.configuracion.set.mutate({
clave: "smtp_host",
valor: "smtp.gmail.com",
tipo: "string",
categoria: "notificacion"
})
```
### Estado de Integraciones
```typescript
// GET /api/trpc/configuracion.integraciones.status
const { meshcentral, librenms, headwind } = await trpc.configuracion.integraciones.status.query()
// Returns: { configurado: boolean, url?: string }
```
### Configurar MeshCentral
```typescript
// POST /api/trpc/configuracion.integraciones.setMeshCentral
await trpc.configuracion.integraciones.setMeshCentral.mutate({
url: "https://mesh.tudominio.com",
user: "admin",
password: "password",
domain: "default"
})
```
## Codigos de Error
| Codigo | Descripcion |
|--------|-------------|
| UNAUTHORIZED | No autenticado |
| FORBIDDEN | Sin permisos |
| NOT_FOUND | Recurso no encontrado |
| CONFLICT | Conflicto (ej: email duplicado) |
| BAD_REQUEST | Request invalido |
| INTERNAL_SERVER_ERROR | Error del servidor |
## Rate Limiting
- API general: 100 requests/minuto
- Autenticacion: 10 requests/minuto
- Acciones sensibles (wipe, commands): 5 requests/minuto
## Webhooks
Las alertas pueden enviar webhooks a URLs configuradas:
```json
{
"id": "alert-id",
"severidad": "CRITICAL",
"titulo": "Servidor offline",
"mensaje": "El servidor SRV-01 no responde",
"dispositivo": "SRV-01",
"cliente": "Cliente A",
"timestamp": "2024-01-15T10:30:00Z"
}
```

321
docs/arquitectura/README.md Normal file
View File

@@ -0,0 +1,321 @@
# Arquitectura del Sistema
## Vision General
MSP Monitor Dashboard es una aplicacion web moderna construida con una arquitectura monolitica modular, diseñada para ejecutarse en una unica VM de Proxmox mientras mantiene una clara separacion de responsabilidades.
```
┌─────────────────────────────────────────────────────────────────┐
│ NGINX (Proxy) │
│ SSL/TLS + Rate Limiting │
└─────────────────────────────────────────────────────────────────┘
┌───────────────┴───────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────────┐
│ Next.js Dashboard │ │ Background Workers │
│ (Frontend + API Routes) │ │ (BullMQ Jobs) │
└───────────────────────────┘ └───────────────────────────────┘
│ │
└───────────────┬───────────────┘
┌───────────────────────┼───────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ PostgreSQL │ │ Redis │ │ External │
│ (Primary) │ │ (Cache/Queue) │ │ APIs │
└───────────────┘ └───────────────┘ └───────────────┘
┌───────────────────────────────┼───────────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ MeshCentral │ │ LibreNMS │ │ Headwind MDM │
│ (PC/Laptop) │ │ (Network) │ │ (Mobile) │
└───────────────┘ └───────────────┘ └───────────────┘
```
## Componentes Principales
### 1. Frontend (Next.js + React)
**Ubicacion**: `src/app/`, `src/components/`
El frontend utiliza Next.js 14 con App Router, proporcionando:
- **Server Components**: Para renderizado del lado del servidor
- **Client Components**: Para interactividad en el navegador
- **Tailwind CSS**: Sistema de diseño con tema oscuro cyan/navy
- **React Query**: Cache y sincronizacion de estado del servidor
**Estructura de paginas**:
```
src/app/
├── (dashboard)/ # Grupo de rutas autenticadas
│ ├── layout.tsx # Layout con sidebar y header
│ ├── page.tsx # Dashboard principal
│ ├── equipos/ # Gestion de PCs/laptops/servidores
│ ├── celulares/ # Gestion de dispositivos moviles
│ ├── red/ # Gestion de dispositivos de red
│ ├── alertas/ # Centro de alertas
│ ├── reportes/ # Generacion de reportes
│ └── configuracion/ # Configuracion del sistema
└── api/ # API Routes
└── trpc/ # Endpoint tRPC
```
### 2. Backend (tRPC + Prisma)
**Ubicacion**: `src/server/trpc/`
El backend utiliza tRPC para APIs type-safe con validacion Zod:
```typescript
// Ejemplo de router
export const equiposRouter = router({
list: protectedProcedure
.input(z.object({ clienteId: z.string().optional() }))
.query(async ({ ctx, input }) => {
return ctx.prisma.dispositivo.findMany({
where: input.clienteId ? { clienteId: input.clienteId } : {},
})
}),
})
```
**Routers disponibles**:
- `auth` - Autenticacion y sesiones
- `clientes` - Gestion de clientes/tenants
- `equipos` - PCs, laptops, servidores
- `celulares` - Dispositivos moviles
- `red` - Dispositivos de red
- `alertas` - Sistema de alertas
- `reportes` - Generacion de reportes
- `usuarios` - Gestion de usuarios
- `configuracion` - Configuracion del sistema
### 3. Servicios de Integracion
**Ubicacion**: `src/server/services/`
Clientes para comunicacion con sistemas externos:
```
services/
├── meshcentral/
│ └── client.ts # Cliente API REST + WebSocket
├── librenms/
│ └── client.ts # Cliente API REST
└── headwind/
└── client.ts # Cliente API REST
```
Cada cliente proporciona:
- Autenticacion automatica
- Manejo de errores
- Tipado TypeScript
- Cache de conexiones
### 4. Sistema de Jobs (BullMQ)
**Ubicacion**: `src/server/jobs/`
Procesamiento asincronico con BullMQ y Redis:
```
jobs/
├── queue.ts # Configuracion de colas
├── worker.ts # Worker principal
├── sync-meshcentral.job.ts
├── sync-librenms.job.ts
├── sync-headwind.job.ts
├── alert-processor.job.ts
├── notification.job.ts
└── maintenance.job.ts
```
**Colas**:
| Cola | Proposito | Frecuencia |
|------|-----------|------------|
| sync | Sincronizacion con plataformas | Cada 5 min |
| alerts | Procesamiento de alertas | Bajo demanda |
| notifications | Envio de notificaciones | Bajo demanda |
| maintenance | Tareas de mantenimiento | Diario/Horario |
### 5. Base de Datos (PostgreSQL + Prisma)
**Ubicacion**: `prisma/schema.prisma`
Modelo de datos multi-tenant:
```
┌─────────────┐ ┌─────────────────┐
│ Cliente │────<│ Dispositivo │
└─────────────┘ └─────────────────┘
│ │
│ ┌───────┴───────┐
│ ▼ ▼
│ ┌───────────────┐ ┌───────────────┐
│ │ Metrica │ │ Software │
│ └───────────────┘ └───────────────┘
├───<│ Usuario │
└───<│ Alerta │
```
**Tablas principales**:
- `clientes` - Tenants del sistema
- `dispositivos` - Todos los tipos de dispositivos
- `alertas` - Alertas y eventos
- `usuarios` - Usuarios y permisos
- `configuracion` - Settings del sistema
## Flujo de Datos
### 1. Sincronizacion de Dispositivos
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Plataforma │────>│ Worker │────>│ PostgreSQL │
│ Externa │ │ (BullMQ) │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
▲ │
│ ▼
│ ┌─────────────┐
│ │ Redis │
│ │ (Cache) │
│ └─────────────┘
│ │
│ ▼
│ ┌─────────────┐
└────────────│ Alerta │
│ Processor │
└─────────────┘
```
### 2. Consulta de Dispositivos
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Browser │────>│ Next.js │────>│ tRPC │
│ │<────│ (SSR) │<────│ Router │
└─────────────┘ └─────────────┘ └─────────────┘
┌─────────────┐
│ Prisma │
│ Client │
└─────────────┘
┌───────────────────┴───────────────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Redis │ │ PostgreSQL │
│ (Cache) │ │ │
└─────────────┘ └─────────────┘
```
### 3. Sesion Remota
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Usuario │────>│ Dashboard │────>│ MeshCentral │
│ │ │ │ │ (iframe) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Audit Log │<───────────┘
│ └─────────────┘
┌─────────────────────────────────────────────────────┐
│ WebSocket (MeshCentral) │
│ Desktop / Terminal / Files │
└─────────────────────────────────────────────────────┘
```
## Seguridad
### Autenticacion
- **MeshCentral SSO**: Integracion con autenticacion de MeshCentral
- **JWT Sessions**: Tokens firmados con expiracion de 24h
- **Password Hashing**: bcrypt con salt factor 12
### Autorizacion
```typescript
// Roles jerarquicos
enum RolUsuario {
SUPER_ADMIN, // Acceso total
ADMIN, // Admin de cliente
TECNICO, // Operaciones
CLIENTE, // Solo lectura
VIEWER // Vista limitada
}
```
### Aislamiento de Datos
- Cada consulta filtra por `clienteId`
- Middleware verifica permisos en cada request
- Audit log de todas las acciones sensibles
## Escalabilidad
### Horizontal (futuro)
```
┌─────────────┐
│ HAProxy │
│ (LB) │
└─────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Node 1 │ │ Node 2 │ │ Node 3 │
│ (Next.js) │ │ (Next.js) │ │ (Worker) │
└───────────┘ └───────────┘ └───────────┘
│ │ │
└───────────────┼───────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ PostgreSQL│ │ Redis │ │ Redis │
│ Primary │ │ Primary │ │ Replica │
└───────────┘ └───────────┘ └───────────┘
```
### Vertical (actual)
- **CPU**: Escalable segun carga
- **RAM**: Minimo 4GB recomendado
- **Disco**: SSD para BD, puede usar storage separado para backups
## Monitoreo del Sistema
### Health Checks
```bash
# Endpoints de health
GET /health # Estado general
GET /api/health # Estado de API
```
### Metricas
- CPU/RAM/Disco del servidor
- Latencia de BD
- Tamano de colas
- Errores de sincronizacion
### Logs
```bash
# Ver logs de contenedores
docker-compose logs -f dashboard
docker-compose logs -f worker
```

332
docs/guias/configuracion.md Normal file
View File

@@ -0,0 +1,332 @@
# Guia de Configuracion
## Configuracion General
### Variables de Entorno
El archivo `.env` contiene toda la configuracion del sistema:
```env
# ==================== BASE DE DATOS ====================
# URL de conexion a PostgreSQL
DATABASE_URL="postgresql://usuario:password@host:5432/database?schema=public"
# Credenciales para Docker
POSTGRES_USER=mspmonitor
POSTGRES_PASSWORD=password-seguro
POSTGRES_DB=msp_monitor
# ==================== CACHE Y COLAS ====================
# URL de conexion a Redis
REDIS_URL="redis://localhost:6379"
# ==================== SEGURIDAD ====================
# Clave secreta para JWT (minimo 32 caracteres)
JWT_SECRET="clave-muy-segura-de-al-menos-32-caracteres"
# ==================== INTEGRACIONES ====================
# MeshCentral
MESHCENTRAL_URL="https://mesh.tudominio.com"
MESHCENTRAL_USER="admin"
MESHCENTRAL_PASS="password"
MESHCENTRAL_DOMAIN="default"
# LibreNMS
LIBRENMS_URL="https://librenms.tudominio.com"
LIBRENMS_TOKEN="tu-token-api"
# Headwind MDM
HEADWIND_URL="https://mdm.tudominio.com"
HEADWIND_TOKEN="tu-token-api"
# ==================== NOTIFICACIONES ====================
# SMTP
SMTP_HOST="smtp.gmail.com"
SMTP_PORT="587"
SMTP_USER="tu-email@gmail.com"
SMTP_PASS="tu-app-password"
SMTP_FROM="MSP Monitor <noreply@tudominio.com>"
# Twilio (opcional)
TWILIO_ACCOUNT_SID=""
TWILIO_AUTH_TOKEN=""
TWILIO_PHONE_NUMBER=""
# ==================== APLICACION ====================
# URL publica de la aplicacion
NEXT_PUBLIC_APP_URL="https://monitor.tudominio.com"
# Entorno
NODE_ENV="production"
```
## Configuracion de Integraciones
### MeshCentral
1. **Crear usuario API en MeshCentral**:
- Acceder a MeshCentral como admin
- Ir a "My Account" > "Security" > "Create Login Token"
- O crear usuario dedicado con permisos de API
2. **Configurar en el dashboard**:
- Ir a Configuracion > Integraciones
- Ingresar URL, usuario y password
- Probar conexion
3. **Mapear grupos**:
- Cada cliente puede tener un grupo de MeshCentral asignado
- Los dispositivos del grupo se sincronizaran automaticamente
### LibreNMS
1. **Crear API Token en LibreNMS**:
- Ir a "Settings" > "API" > "API Settings"
- Crear nuevo token con permisos de lectura
2. **Configurar en el dashboard**:
- Ir a Configuracion > Integraciones
- Ingresar URL y token
- Probar conexion
3. **Mapear grupos de dispositivos**:
- Crear grupos en LibreNMS para cada cliente
- Asignar el grupo al cliente en el dashboard
### Headwind MDM
1. **Obtener API Token**:
- Acceder a panel de admin de Headwind
- Ir a configuracion de API
- Copiar token de acceso
2. **Configurar en el dashboard**:
- Ir a Configuracion > Integraciones
- Ingresar URL y token
- Probar conexion
## Configuracion de Notificaciones
### Email (SMTP)
Para Gmail:
1. Habilitar autenticacion de dos factores
2. Crear "App Password" en configuracion de seguridad
3. Usar el app password en `SMTP_PASS`
```env
SMTP_HOST="smtp.gmail.com"
SMTP_PORT="587"
SMTP_USER="tu-cuenta@gmail.com"
SMTP_PASS="xxxx-xxxx-xxxx-xxxx" # App password
SMTP_FROM="MSP Monitor <noreply@tudominio.com>"
```
Para otros proveedores:
| Proveedor | Host | Puerto |
|-----------|------|--------|
| Gmail | smtp.gmail.com | 587 |
| Office 365 | smtp.office365.com | 587 |
| SendGrid | smtp.sendgrid.net | 587 |
| Mailgun | smtp.mailgun.org | 587 |
### SMS (Twilio)
1. Crear cuenta en Twilio
2. Obtener Account SID y Auth Token
3. Comprar numero de telefono
4. Configurar en `.env`:
```env
TWILIO_ACCOUNT_SID="ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
TWILIO_AUTH_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
TWILIO_PHONE_NUMBER="+1234567890"
```
### Webhooks
Los webhooks se configuran por regla de alerta:
1. Crear regla de alerta
2. Habilitar "Notificar por Webhook"
3. Ingresar URL del endpoint
Formato del payload:
```json
{
"id": "alert-id",
"severidad": "CRITICAL",
"titulo": "Titulo de la alerta",
"mensaje": "Descripcion detallada",
"dispositivo": "Nombre del dispositivo",
"cliente": "Nombre del cliente",
"timestamp": "2024-01-15T10:30:00Z"
}
```
## Configuracion de Usuarios y Permisos
### Roles de Usuario
| Rol | Descripcion | Permisos |
|-----|-------------|----------|
| SUPER_ADMIN | Administrador global | Todo |
| ADMIN | Admin de cliente | Gestion de su cliente |
| TECNICO | Soporte tecnico | Operaciones y monitoreo |
| CLIENTE | Usuario cliente | Solo lectura |
| VIEWER | Vista limitada | Dashboard basico |
### Crear Usuario
1. Ir a Configuracion > Usuarios
2. Click en "Nuevo Usuario"
3. Completar:
- Email
- Nombre
- Rol
- Cliente (opcional)
- Password (o usar SSO de MeshCentral)
### Permisos Granulares
Ademas del rol, se pueden asignar permisos especificos:
```
recursos: dispositivos, alertas, reportes, configuracion, usuarios
acciones: read, write, delete, execute
```
## Configuracion de Alertas
### Reglas Predefinidas
El sistema incluye reglas por defecto:
| Regla | Metrica | Umbral | Severidad |
|-------|---------|--------|-----------|
| CPU Alta | cpu | > 90% | WARNING |
| CPU Critica | cpu | > 95% | CRITICAL |
| RAM Alta | ram | > 85% | WARNING |
| Disco Lleno | disco | > 90% | WARNING |
| Temperatura Alta | temperatura | > 80 | WARNING |
| Bateria Baja | bateria | < 15 | WARNING |
### Crear Regla Personalizada
1. Ir a Alertas > Reglas
2. Click en "Nueva Regla"
3. Configurar:
- Nombre descriptivo
- Tipo de dispositivo (opcional)
- Metrica a monitorear
- Condicion (>, <, >=, <=, ==)
- Valor umbral
- Duracion minima (evitar falsos positivos)
- Severidad
- Canales de notificacion
## Configuracion de Backups
### Backup Automatico
Agregar al crontab del servidor:
```bash
# Backup diario a las 2am
0 2 * * * /opt/msp-monitor/scripts/backup-db.sh >> /var/log/msp-backup.log 2>&1
```
### Configuracion de Backup
Variables en `.env`:
```env
# Directorio de backups
BACKUP_DIR="/backups"
# Dias de retencion
RETENTION_DAYS=30
# S3 (opcional)
S3_BUCKET="mi-bucket-backups"
AWS_ACCESS_KEY_ID="..."
AWS_SECRET_ACCESS_KEY="..."
```
### Restaurar Backup
```bash
./scripts/restore-db.sh /backups/msp_monitor_20240115_020000.sql.gz
```
## Configuracion de SSL
### Renovacion Automatica
El contenedor de Certbot renueva automaticamente. Verificar:
```bash
docker compose -f docker/docker-compose.yml logs certbot
```
### Certificado Manual
1. Copiar certificados a `docker/nginx/ssl/`
2. Actualizar paths en `docker/nginx/conf.d/default.conf`
3. Reiniciar Nginx: `docker compose restart nginx`
## Configuracion de Logs
### Niveles de Log
En `.env`:
```env
# Nivel de log: debug, info, warn, error
LOG_LEVEL="info"
```
### Rotacion de Logs
Docker maneja la rotacion. Configurar en `/etc/docker/daemon.json`:
```json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
```
## Personalizacion
### Tema Visual
Editar `tailwind.config.ts` para cambiar colores:
```typescript
colors: {
primary: {
500: '#06b6d4', // Color principal
// ...
},
// ...
}
```
### Logo
Reemplazar archivo en `public/logo.png`
### Titulo
Editar `src/app/layout.tsx`:
```typescript
export const metadata: Metadata = {
title: 'Mi Dashboard MSP',
// ...
}
```

359
docs/guias/instalacion.md Normal file
View File

@@ -0,0 +1,359 @@
# Guia de Instalacion
## Requisitos del Sistema
### Hardware Minimo
| Componente | Minimo | Recomendado |
|------------|--------|-------------|
| CPU | 2 cores | 4+ cores |
| RAM | 4 GB | 8+ GB |
| Disco | 40 GB SSD | 100+ GB SSD |
| Red | 100 Mbps | 1 Gbps |
### Software
- **Sistema Operativo**: Ubuntu 22.04 LTS o Debian 12
- **Docker**: 24.0+
- **Docker Compose**: 2.20+
- **Node.js**: 20.x (solo para desarrollo)
### Requisitos de Red
- Puerto 80 (HTTP)
- Puerto 443 (HTTPS)
- Puerto 5432 (PostgreSQL, solo interno)
- Puerto 6379 (Redis, solo interno)
- Acceso a MeshCentral, LibreNMS y/o Headwind MDM
## Instalacion en Produccion
### 1. Preparar el Servidor
```bash
# Actualizar sistema
sudo apt update && sudo apt upgrade -y
# Instalar dependencias
sudo apt install -y curl git
# Instalar Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Agregar usuario al grupo docker
sudo usermod -aG docker $USER
newgrp docker
# Instalar Docker Compose
sudo apt install -y docker-compose-plugin
```
### 2. Clonar el Repositorio
```bash
# Crear directorio
sudo mkdir -p /opt/msp-monitor
cd /opt/msp-monitor
# Clonar repositorio
git clone https://git.consultoria-as.com/msp/msp-monitor-dashboard.git .
# Configurar permisos
sudo chown -R $USER:$USER /opt/msp-monitor
```
### 3. Configurar Variables de Entorno
```bash
# Copiar archivo de ejemplo
cp .env.example .env
# Editar configuracion
nano .env
```
Configuracion minima requerida:
```env
# Seguridad - CAMBIAR ESTOS VALORES
POSTGRES_PASSWORD=<password-seguro>
JWT_SECRET=<clave-jwt-minimo-32-caracteres>
# MeshCentral (opcional si no se usa)
MESHCENTRAL_URL=https://mesh.tudominio.com
MESHCENTRAL_USER=admin
MESHCENTRAL_PASS=password
MESHCENTRAL_DOMAIN=default
# LibreNMS (opcional si no se usa)
LIBRENMS_URL=https://librenms.tudominio.com
LIBRENMS_TOKEN=tu-api-token
# Headwind MDM (opcional si no se usa)
HEADWIND_URL=https://mdm.tudominio.com
HEADWIND_TOKEN=tu-api-token
# Email (para notificaciones)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=tu-email@gmail.com
SMTP_PASS=tu-app-password
SMTP_FROM=MSP Monitor <noreply@tudominio.com>
# URL de la aplicacion
APP_URL=https://monitor.tudominio.com
```
### 4. Configurar SSL
#### Opcion A: Certificado Let's Encrypt (recomendado)
```bash
# Crear directorios
mkdir -p docker/nginx/ssl
# Iniciar Nginx sin SSL primero
docker compose -f docker/docker-compose.yml up -d nginx
# Obtener certificado
docker compose -f docker/docker-compose.yml run --rm certbot certonly \
--webroot \
--webroot-path=/var/www/certbot \
-d monitor.tudominio.com \
--email tu-email@tudominio.com \
--agree-tos \
--no-eff-email
# Reiniciar con SSL
docker compose -f docker/docker-compose.yml restart nginx
```
#### Opcion B: Certificado Propio
```bash
# Copiar certificados
cp /ruta/certificado.crt docker/nginx/ssl/live/monitor.tudominio.com/fullchain.pem
cp /ruta/certificado.key docker/nginx/ssl/live/monitor.tudominio.com/privkey.pem
```
### 5. Configurar Nginx
Editar `docker/nginx/conf.d/default.conf`:
```nginx
server {
listen 443 ssl http2;
server_name monitor.tudominio.com; # Cambiar por tu dominio
ssl_certificate /etc/nginx/ssl/live/monitor.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/monitor.tudominio.com/privkey.pem;
# ... resto de configuracion
}
```
### 6. Iniciar Servicios
```bash
# Construir imagenes
docker compose -f docker/docker-compose.yml build
# Iniciar servicios
docker compose -f docker/docker-compose.yml up -d
# Verificar estado
docker compose -f docker/docker-compose.yml ps
```
### 7. Aplicar Migraciones
```bash
# Ejecutar migraciones
docker compose -f docker/docker-compose.yml exec dashboard npx prisma db push
# Verificar conexion a BD
docker compose -f docker/docker-compose.yml exec dashboard npx prisma studio
```
### 8. Crear Usuario Administrador
```bash
# Conectar a la BD
docker compose -f docker/docker-compose.yml exec postgres psql -U mspmonitor -d msp_monitor
# Crear usuario (dentro de psql)
INSERT INTO usuarios (id, email, nombre, password_hash, rol, activo, created_at, updated_at)
VALUES (
gen_random_uuid(),
'admin@tudominio.com',
'Administrador',
'$2a$12$hash-del-password', -- Generar con bcrypt
'SUPER_ADMIN',
true,
NOW(),
NOW()
);
```
O usando el script de setup interactivo:
```bash
./scripts/setup.sh
```
### 9. Verificar Instalacion
1. Acceder a `https://monitor.tudominio.com`
2. Iniciar sesion con las credenciales creadas
3. Verificar conexion a MeshCentral, LibreNMS, Headwind
4. Revisar logs: `docker compose -f docker/docker-compose.yml logs -f`
## Instalacion en Desarrollo
### 1. Requisitos
- Node.js 20+
- npm o yarn
- Docker (para PostgreSQL y Redis)
### 2. Configurar Entorno
```bash
# Clonar repositorio
git clone https://git.consultoria-as.com/msp/msp-monitor-dashboard.git
cd msp-monitor-dashboard
# Instalar dependencias
npm install
# Configurar variables
cp .env.example .env
# Editar .env con configuracion local
```
### 3. Iniciar Servicios de Base de Datos
```bash
# Solo PostgreSQL y Redis
docker compose -f docker/docker-compose.yml up -d postgres redis
```
### 4. Configurar Base de Datos
```bash
# Generar cliente Prisma
npm run db:generate
# Aplicar schema
npm run db:push
# (Opcional) Abrir Prisma Studio
npm run db:studio
```
### 5. Iniciar Desarrollo
```bash
# Iniciar servidor de desarrollo
npm run dev
# En otra terminal, iniciar workers (opcional)
npm run jobs:start
```
Acceder a `http://localhost:3000`
## Actualizacion
### Actualizacion en Produccion
```bash
cd /opt/msp-monitor
# Detener servicios
docker compose -f docker/docker-compose.yml down
# Actualizar codigo
git pull origin main
# Reconstruir imagenes
docker compose -f docker/docker-compose.yml build
# Iniciar servicios
docker compose -f docker/docker-compose.yml up -d
# Aplicar migraciones si hay cambios de BD
docker compose -f docker/docker-compose.yml exec dashboard npx prisma db push
```
### Actualizacion en Desarrollo
```bash
# Actualizar codigo
git pull origin main
# Actualizar dependencias
npm install
# Regenerar cliente Prisma
npm run db:generate
# Aplicar migraciones
npm run db:push
```
## Solucion de Problemas
### Error de Conexion a Base de Datos
```bash
# Verificar que PostgreSQL esta corriendo
docker compose -f docker/docker-compose.yml ps postgres
# Ver logs de PostgreSQL
docker compose -f docker/docker-compose.yml logs postgres
# Verificar conectividad
docker compose -f docker/docker-compose.yml exec postgres pg_isready
```
### Error de Conexion a Redis
```bash
# Verificar que Redis esta corriendo
docker compose -f docker/docker-compose.yml ps redis
# Probar conexion
docker compose -f docker/docker-compose.yml exec redis redis-cli ping
```
### Dashboard no Carga
```bash
# Ver logs del dashboard
docker compose -f docker/docker-compose.yml logs dashboard
# Verificar variables de entorno
docker compose -f docker/docker-compose.yml exec dashboard env
# Reiniciar servicio
docker compose -f docker/docker-compose.yml restart dashboard
```
### Workers no Procesan Jobs
```bash
# Ver logs del worker
docker compose -f docker/docker-compose.yml logs worker
# Verificar colas en Redis
docker compose -f docker/docker-compose.yml exec redis redis-cli KEYS "bull:*"
```
## Proximos Pasos
- [Configuracion del Sistema](configuracion.md)
- [Integracion con MeshCentral](../integraciones/meshcentral.md)
- [Integracion con LibreNMS](../integraciones/librenms.md)
- [Integracion con Headwind MDM](../integraciones/headwind.md)