# Hoja de Ruta - Despliegue infraestructura Sirio > Servidor: sirio.vpn9.com.es > CPU: AMD EPYC 4465P (12c/24t) > RAM: 128 GB > Disco: 4x 1.92 TB NVMe > Fecha inicio: marzo 2026 --- ## Inventario de VMs | # | VM | Hostname | URL panel | CPU | RAM | Disco | Pool NVMe | |---|-----|----------|-----------|-----|-----|-------|-----------| | - | Host PVE | sirio.vpn9.com.es | :8006 (directo) | - | ~4 GB overhead | boot mirror | disco1+disco2 | | 1 | Forgejo | vega.vpn9.com.es | git.vpn9.com.es | existente | existente | existente | - | | 2 | Bastion | polar.vpn9.com.es | - (solo SSH) | 1 vCPU | 1 GB | 20 GB | pool-b | | 3 | WG Hub A | orion.vpn9.com.es | wg.vpn9.com.es | 1 vCPU | 512 MB | 10 GB | pool-b | | 4 | Authentik | atlas.vpn9.com.es | auth.vpn9.com.es | 1-2 vCPU | 2-3 GB | 20 GB | pool-b | | 5 | Netbox | nova.vpn9.com.es | netbox.vpn9.com.es | 1-2 vCPU | 2-3 GB | 20 GB | pool-b | | 6 | Monitoring | rigel.vpn9.com.es | grafana.vpn9.com.es | 4 vCPU | 8-12 GB | 200-500 GB | pool-a | | 7 | Wazuh | altair.vpn9.com.es | wazuh.vpn9.com.es | 4 vCPU | 12 GB | 100 GB | pool-c | | 8 | Servicios | deneb.vpn9.com.es | ansible.vpn9.com.es / status.vpn9.com.es | 1-2 vCPU | 2-3 GB | 20 GB | pool-d | | 9 | Zammad | antares.vpn9.com.es | tickets.vpn9.com.es | 2-3 vCPU | 4-6 GB | 50 GB | pool-c | | 10 | ICSManager | castor.vpn9.com.es | ics.vpn9.com.es | 1-2 vCPU | 2-3 GB | 20 GB | pool-d | | 11 | WildDuck | pollux.vpn9.com.es | correo.vpn9.com.es | 1-2 vCPU | 2-3 GB | 30-50 GB | pool-d | | 12 | PMG | spica.vpn9.com.es | pmg.vpn9.com.es | 1-2 vCPU | 2-3 GB | 30 GB | pool-d | | 13 | PDM | mira.vpn9.com.es | pdm.vpn9.com.es | 1 vCPU | 1-2 GB | 20 GB | pool-d | | 14 | Outline | lyra.vpn9.com.es | docs.vpn9.com.es | 1 vCPU | 1-2 GB | 20 GB | pool-c | | 15 | WG Hub B | betel.vpn9.com.es | - | 1 vCPU | 512 MB | 10 GB | pool-c | ### Distribucion de pools NVMe ``` Disco 1 (1.92TB) Disco 2 (1.92TB) Disco 3 (1.92TB) Disco 4 (1.92TB) ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Boot 100GB │◄─mirror─►│ Boot 100GB │ │ │ │ │ ├──────────────┤ ├──────────────┤ │ │ │ │ │ │ │ │ │ │ │ │ │ pool-a │ │ pool-b │ │ pool-c │ │ pool-d │ │ ~1.8 TB │ │ ~1.8 TB │ │ ~1.9 TB │ │ ~1.9 TB │ │ │ │ │ │ │ │ │ │ Monitoring │ │ Bastion │ │ Wazuh │ │ Servicios │ │ (200-500GB) │ │ WG Hub A │ │ Zammad │ │ ICSManager │ │ │ │ Authentik │ │ Outline │ │ WildDuck │ │ │ │ Netbox │ │ WG Hub B │ │ PMG │ │ │ │ │ │ │ │ PDM │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ ``` Criterio: Monitoring en pool-a solo (ocupa mucho disco). Resto repartido por criticidad: si muere un disco, solo 1/4 de los servicios se cae, el resto sigue. Se restaura desde PBS. --- ## Fase 0: Base del servidor (dia 1) ### 0.1 Instalar Proxmox VE - [ ] Instalar PVE en sirio - [ ] Configurar boot ZFS mirror (disco1 + disco2, particion 100GB) - [ ] Crear pools ZFS independientes: ```bash zpool create pool-a /dev/nvme0n1p3 zpool create pool-b /dev/nvme1n1p3 zpool create pool-c /dev/nvme2n1 zpool create pool-d /dev/nvme3n1 ``` - [ ] Optimizar ZFS en los 4 pools: ```bash for pool in pool-a pool-b pool-c pool-d; do zfs set recordsize=1M $pool zfs set compression=lz4 $pool zfs set atime=off $pool done ``` ### 0.2 Hardening inmediato - [ ] Firewall PVE: activar, policy_out: DROP, policy_in: DROP - [ ] Reglas firewall: permitir SSH (22), PVE web (8006), WireGuard (51820) solo desde IPs conocidas - [ ] SSH: solo key david@ansible, PasswordAuthentication no - [ ] Verificar sshd_config.d no tiene drop-ins peligrosos - [ ] Instalar check_malware.sh (version actualizada con checks 1-21) ### 0.3 WireGuard en el host - [ ] Instalar WireGuard en el host PVE - [ ] Configurar peer temporal hacia hub WG existente - [ ] Verificar conectividad privada con el resto de la infra - [ ] Registrar sirio en DNS interno (Technitium cuando exista, /etc/hosts mientras tanto) --- ## Fase 1: Fundamentos (semana 1) ### 1.1 VM Forgejo (vega) - [ ] Migrar o conectar Forgejo existente - [ ] Crear repos para: - `infra-ansible` (playbooks y roles) - `infra-configs` (backup de configs, capa 6.3) - `infra-docs` (documentacion operativa) - [ ] Verificar acceso por WG ### 1.2 VM Bastion (polar) - [ ] Crear VM: 1 vCPU, 1 GB RAM, 20 GB disco en pool-b - [ ] Debian 12 minimal - [ ] SSH hardened (solo key david@ansible) - [ ] Instalar Claude Code: ```bash curl -fsSL https://claude.ai/install.sh | bash ``` - [ ] Crear /root/CLAUDE.md con contexto de la infra - [ ] Este es el punto de entrada SSH para tecnicos, nunca SSH directo al host PVE ### 1.3 VM WG Hub A (orion) - [ ] Crear VM: 1 vCPU, 512 MB RAM, 10 GB disco en pool-b - [ ] Debian 12 minimal + WireGuard - [ ] Configurar como hub central WG (reemplaza el peer temporal del host) - [ ] nftables con politica restrictiva: ``` Puerto 25: BLOQUEADO siempre Puertos 465/587: whitelist SMTP Puertos 80/443/53/123: permitidos Resto: DROP + log ``` - [ ] NAT CGNAT (100.64.0.0/10) para VMs de clientes - [ ] Instalar wgdashboard - [ ] URL: wg.vpn9.com.es (via Traefik, solo VPN) --- ## Fase 2: Identidad e inventario (semana 1-2) ### 2.1 VM Authentik (atlas) - [ ] Crear VM: 1-2 vCPU, 2-3 GB RAM, 20 GB disco en pool-b - [ ] Desplegar Authentik (Docker) - [ ] Configurar como proveedor OIDC/SAML central - [ ] Crear usuarios del equipo tecnico - [ ] URL: auth.vpn9.com.es - [ ] Integrar con Grafana, Netbox, Zammad, Outline, Forgejo (cuando se desplieguen) ### 2.2 VM Netbox (nova) - [ ] Crear VM: 1-2 vCPU, 2-3 GB RAM, 20 GB disco en pool-b - [ ] Desplegar Netbox (Docker) - [ ] Configurar IPAM: - Prefijo WG: 10.9.0.0/16 - Prefijo CGNAT: 100.64.0.0/10 (un /24 por cliente) - IPv6 WG: fdab::/48 - [ ] Registrar todas las VMs ya desplegadas (sirio, vega, polar, orion, atlas, nova) - [ ] URL: netbox.vpn9.com.es - [ ] Integrar con Authentik (SSO) --- ## Fase 3: Observabilidad (semana 2-3) ### 3.1 VM Monitoring (rigel) - [ ] Crear VM: 4 vCPU, 8-12 GB RAM, 200-500 GB disco en pool-a - [ ] Desplegar stack de monitoring (Docker): - VictoriaMetrics (metricas, retencion 1 año) - vmagent (scrape de metricas) - Grafana (dashboards) - Loki (logs, retencion 30 dias) - Alertmanager (alertas → Zammad cuando exista, email mientras tanto) - [ ] URL: grafana.vpn9.com.es - [ ] Integrar con Authentik (SSO) - [ ] Instalar en TODAS las VMs existentes: ```bash # En cada VM apt install prometheus-node-exporter # + Grafana Alloy para logs a Loki ``` - [ ] Crear dashboards basicos: host PVE, VMs, discos ZFS ### 3.2 VM Wazuh (altair) - [ ] Crear VM: 4 vCPU, 12 GB RAM, 100 GB disco en pool-c - [ ] Desplegar Wazuh Manager + Dashboard (Docker o paquetes) - [ ] URL: wazuh.vpn9.com.es - [ ] Instalar Wazuh Agent en TODAS las VMs existentes + host PVE - [ ] Configurar FIM (File Integrity Monitoring): - /etc/pam.d/ - /etc/ssh/sshd_config.d/ - /etc/ld.so.preload - /usr/bin/ (binarios nuevos) - /usr/lib/systemd/system/ (services nuevos) - [ ] Configurar alerta nivel ≥10 → email (→ Zammad cuando exista) ### 3.3 Instalar agentes en todo lo existente - [ ] Por cada VM ya desplegada (polar, orion, atlas, nova, rigel, altair): - [ ] node_exporter - [ ] Grafana Alloy (logs → Loki) - [ ] Wazuh Agent - [ ] Verificar que aparece en Grafana y Wazuh Dashboard --- ## Fase 4: Servicios operativos (semana 3-4) ### 4.1 VM Servicios (deneb) - [ ] Crear VM: 1-2 vCPU, 2-3 GB RAM, 20 GB disco en pool-d - [ ] Desplegar (Docker): - Semaphore (UI para Ansible) - Uptime Kuma (status page) - Technitium (DNS interno) - Traefik (reverse proxy central) - [ ] Configurar Traefik: - Certs Let's Encrypt para *.vpn9.com.es - Middleware ipAllowList (solo IPs WG) - Catch-all: pagina "acceso solo por VPN" para peticiones externas - Routers para todos los servicios ya desplegados - [ ] URLs: ansible.vpn9.com.es, status.vpn9.com.es - [ ] Configurar Technitium como DNS interno: - Zona vpn9.com.es con todos los hostnames - Todas las VMs apuntan a Technitium como DNS - [ ] Semaphore: conectar a Forgejo (repos ansible), configurar inventario desde Netbox - [ ] Uptime Kuma: añadir checks de todos los servicios desplegados ### 4.2 VM Zammad (antares) - [ ] Crear VM: 2-3 vCPU, 4-6 GB RAM, 50 GB disco en pool-c - [ ] Desplegar Zammad (Docker) - [ ] URL: tickets.vpn9.com.es - [ ] Integrar con Authentik (SSO) - [ ] Configurar Alertmanager → Zammad (webhook, crea tickets de alertas) - [ ] Configurar Wazuh → Zammad (alertas nivel ≥10) - [ ] Crear colas: infraestructura, clientes, seguridad ### 4.3 Traefik: pagina VPN para accesos externos - [ ] Contenedor nginx con pagina estatica de instrucciones - [ ] Traefik catch-all redirige ahi si la IP no es WG - [ ] Pagina muestra: como instalar WireGuard, a quien contactar --- ## Fase 5: Migracion de servicios existentes (semana 4+) ### 5.1 VM ICSManager (castor) - [ ] Crear VM: 1-2 vCPU, 2-3 GB RAM, 20 GB disco en pool-d - [ ] Migrar ICSManager (Docker: app + PostgreSQL, todo dentro, caja negra) - [ ] URL: ics.vpn9.com.es - [ ] Verificar integracion con Netbox (inventario de clientes) ### 5.2 VM WildDuck (pollux) - [ ] Crear VM: 1-2 vCPU, 2-3 GB RAM, 30-50 GB disco en pool-d - [ ] Migrar WildDuck (Docker: WildDuck + MongoDB + Redis, todo dentro) - [ ] URL: correo.vpn9.com.es - [ ] Verificar tokens SMTP de los PVE (notificaciones) - [ ] No migrar hasta tener PMG listo o al menos planificado ### 5.3 VM PMG (spica) - [ ] Crear VM: 1-2 vCPU, 2-3 GB RAM, 30 GB disco en pool-d - [ ] Instalar Proxmox Mail Gateway - [ ] Configurar como relay MX delante de WildDuck: ``` Internet → PMG (spica) → WildDuck (pollux) ``` - [ ] Configurar: SpamAssassin, ClamAV, greylisting, SPF/DKIM/DMARC - [ ] URL: pmg.vpn9.com.es - [ ] Redirigir MX del dominio a PMG ### 5.4 VM PDM (mira) - [ ] Crear VM: 1 vCPU, 1-2 GB RAM, 20 GB disco en pool-d - [ ] Instalar Proxmox Datacenter Manager - [ ] Conectar todos los clusters PVE - [ ] URL: pdm.vpn9.com.es ### 5.5 VM Outline (lyra) - [ ] Crear VM: 1 vCPU, 1-2 GB RAM, 20 GB disco en pool-c - [ ] Desplegar Outline (Docker: app + PostgreSQL + Redis) - [ ] URL: docs.vpn9.com.es - [ ] Integrar con Authentik (SSO) - [ ] Migrar documentacion operativa aqui ### 5.6 VM WG Hub B (betel) - [ ] Crear VM: 1 vCPU, 512 MB RAM, 10 GB disco en pool-c - [ ] Clon de la config de orion (WG Hub A) - [ ] Configurar keepalived HA con orion - [ ] Peer de failover: si orion cae, betel toma el relevo --- ## Fase 6: Backup y contingencia (en paralelo desde fase 3) ### 6.1 Backup de las VMs de sirio - [ ] Configurar PBS1 (existente) para backupear todas las VMs de sirio - [ ] Schedule: diario, retencion 7 dias minimo - [ ] Verificar restauracion de al menos 1 VM como test ### 6.2 Backup de configs a git (capa 6.3) - [ ] Crear playbook backup-configs.yml en Semaphore: ``` Recoger: /etc/pve/, /etc/proxmox-backup/, WG configs, ZFS properties Commit + push a repo infra-configs en Forgejo Schedule: diario 06:00 ``` ### 6.3 Replica ZFS a oficina (capa 6.4) - [ ] Configurar zfs send/recv incremental cada 4h - [ ] VMs a replicar: rigel (monitoring), altair (wazuh), deneb (servicios) - [ ] Destino: servidor Xeon 96GB en oficina via WireGuard - [ ] Documentar procedimiento de activacion en caso de perdida de sirio ### 6.4 Test de contingencia - [ ] Simular perdida de 1 pool NVMe: restaurar VMs desde PBS - [ ] Medir tiempo de restauracion - [ ] Documentar en Outline --- ## Fase 7: Agentes IA (mes 2-4) ### 7.1 Claude Code en bastion (dia 1 de fase 1) - [ ] Ya instalado en polar (bastion) en fase 1.2 - [ ] Crear CLAUDE.md con contexto completo de la infra ### 7.2 Agente triaje de alertas (mes 2) - [ ] Crear workflow en n8n (dentro de deneb): - Trigger: webhook desde Alertmanager - Consulta: VictoriaMetrics + Loki + Netbox - Analisis: Claude API (Sonnet) - Accion: crear ticket en Zammad con diagnostico - [ ] Coste estimado: ~$15-30/mes ### 7.3 Agente capacity planning (mes 3) - [ ] Workflow n8n: cron semanal lunes 08:00 - [ ] Genera informe en Outline con predicciones de espacio ### 7.4 Agente seguridad Wazuh (mes 3-4) - [ ] Workflow n8n: webhook desde Wazuh (alertas nivel ≥10) - [ ] Analisis con Claude API (Opus) - [ ] Clasifica: falso positivo / incidente real / indeterminado --- ## Checklist por VM (aplicar a cada VM al desplegarla) Antes de pasar a la siguiente VM, verificar: - [ ] node_exporter instalado y scrapeado por VictoriaMetrics - [ ] Grafana Alloy instalado y enviando logs a Loki - [ ] Wazuh Agent instalado y reportando al manager - [ ] Registrada en Netbox (hostname, IP, rol, cliente: interno) - [ ] Añadida a Uptime Kuma (check HTTP o TCP) - [ ] Firewall de la VM configurado (solo puertos necesarios) - [ ] DNS registrado en Technitium (hostname.vpn9.com.es) - [ ] Router Traefik configurado (si tiene panel web) - [ ] Backup PBS verificado (al menos 1 backup exitoso) --- ## Resumen de recursos ``` Total VMs: 15 (+ host PVE) Total vCPU: ~24-32 Total RAM: ~44-58 GB (de 128 GB disponibles) Total disco: ~580-920 GB (de 7.68 TB disponibles) Margen RAM: ~70-84 GB libres Margen disco: ~6.8-7.1 TB libres Coste API Claude: ~$30-60/mes ``` --- ## Documentos de referencia | Documento | Contenido | |-----------|-----------| | decision-logs.md | Capa 1: Monitoring y logs centralizados | | decision-incidentes.md | Capa 2: Seguridad y respuesta a incidentes | | decision-automatizacion.md | Capa 3: Ansible + Semaphore + CI/CD | | decision-red.md | Capa 4: WireGuard, CGNAT, VM model, PDM, PMG | | decision-almacenamiento.md | Capa 6: Backup 3 capas, config backup, replica oficina | | decision-observabilidad.md | Capa 7: Dashboards, SLOs, capacity planning | | decision-ia-agentes.md | Capa 8: Claude Code + agentes automatizados | | guia-deteccion-xmrig.md | IOCs y procedimiento de deteccion de malware | | check_malware.sh | Script de verificacion de malware (ejecutar en todos los servidores) | | articulos-seguridad-lecciones.md | 177 articulos para blog (29 bloques) |