Este artículo cierra una serie que empezó con una auditoría de seguridad y acabó con algo que llevaba meses intentando sin éxito: reducir dos servidores a uno.
No fue un proceso limpio. Hubo intentos fallidos, más de 48 horas peleando con configuraciones que no funcionaban, y finalmente echar atrás todo el trabajo. Pero esta vez salió. Y la solución fue bastante más simple de lo que habíamos intentado antes.
Cómo llegamos hasta aquí
Todo empezó mucho antes de esta serie. Durante un tiempo, el homelab era accesible desde el exterior mediante Cloudflare Tunnel — una solución cómoda pero con limitaciones técnicas importantes: poco control sobre el tráfico, dependencia total de un servicio externo y restricciones en el tipo de aplicaciones que podías exponer. En su momento documenté tanto cómo montar los túneles en Proxmox como cómo gestionar los certificados SSL con Cloudflare y Let's Encrypt.
La alternativa fue montar un VPS en Hetzner dedicado exclusivamente a hacer de punto de entrada — y documenté también esa migración. Un servidor ligero con Nginx Proxy Manager en Docker, conectado al homelab via WireGuard. Sin Cloudflare Tunnel de por medio, con control total sobre el tráfico, los certificados y las configuraciones. Hetzner da exactamente eso: infraestructura flexible, con acceso root completo, sin las limitaciones de un hosting compartido.
Poco después llegó la migración de las webs de clientes y proyectos propios. Webempresa había sido una buena solución durante años — fiable, con buen soporte — pero un hosting compartido tiene un techo técnico. Cuando las necesidades crecen, necesitas más control: versiones de PHP específicas, configuraciones de Nginx a medida, acceso a los logs, scripts propios en cron. Hetzner lo permite sin restricciones. Así que las webs también se mudaron, a un segundo VPS dedicado a producción.
El resultado fue una infraestructura con dos VPS bien diferenciados: uno para las webs, otro como proxy del homelab. Funcionaba, pero era más complejo de mantener de lo necesario.
El objetivo: un solo servidor
La idea de consolidar todo en un único VPS llevaba rondando desde el principio. Un solo servidor gestionando tanto las webs de producción como el proxy hacia el homelab — menos puntos de fallo, menos configuraciones que sincronizar, más fácil de auditar y mantener.
El problema era técnico, y tardó varios intentos en resolverse.
Lo que no funcionó
El primer intento fue usar Nginx con el módulo stream para hacer SNI pass-through — dejar pasar las conexiones SSL sin terminarlas en el VPS, y que el Nginx Proxy Manager del homelab gestionara los certificados. El problema es que Nginx no puede gestionar stream y http en el mismo proceso de forma limpia cuando hay muchos vhosts. Colisiones de puertos, configuraciones que se pisaban entre sí. Más de 48 horas después, vuelta al punto de partida.
Lo que funcionó
La solución fue terminar el SSL en el VPS y hacer el proxy hacia cada servicio del homelab directamente, sin intermediarios.
La clave que faltaba en los intentos anteriores era el certificado wildcard. Sin él, necesitabas un certificado individual por cada subdominio — inmanejable con más de una docena de servicios. Con él, un único certificado cubre todos los subdominios y el problema desaparece.
Certbot con validación DNS via Cloudflare lo genera en segundos:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/mi-dominio.ini \
-d "mi-dominio.casa" \
-d "*.mi-dominio.casa" \
--preferred-challenges dns-01A partir de ahí, cada servicio del homelab tiene su propio bloque en Nginx. El patrón es siempre el mismo — cambia el subdominio y la IP interna:
server {
listen 443 ssl;
server_name servicio.mi-dominio.casa;
ssl_certificate /etc/letsencrypt/live/mi-dominio.casa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mi-dominio.casa/privkey.pem;
location / {
proxy_pass http://192.168.1.XX:PUERTO;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Los dos últimos headers — Upgrade y Connection — son necesarios para los servicios que usan WebSocket. Sin ellos, la interfaz carga pero aparece vacía.
Para servicios con HTTPS interno y certificado autofirmado (como Proxmox o PBS), hay que añadir:
proxy_pass https://192.168.1.XX:PUERTO;
proxy_set_header Host 192.168.1.XX:PUERTO;
proxy_ssl_verify off;
proxy_ssl_server_name off;La estrategia de migración
Lo que marcó la diferencia respecto a los intentos anteriores fue hacerlo de uno en uno, no todo de golpe.
Empezamos con un único servicio poco crítico para validar que toda la cadena funcionaba: que el DNS llegaba al VPS, que Nginx lo procesaba, que el túnel WireGuard llevaba la petición hasta el homelab y que la respuesta volvía correctamente. Una vez confirmado, los demás fueron copy-paste con ajustes mínimos.
Cloudflare facilitó mucho la transición. Teníamos un registro wildcard apuntando al VPS antiguo. Creando registros individuales para cada subdominio — que tienen prioridad sobre el wildcard — pudimos migrar uno a uno sin afectar al resto. El wildcard siguió cubriendo los servicios no migrados hasta que el último estuvo listo.
El resultado
Un único VPS gestionando las webs de producción y haciendo de proxy inverso para todos los servicios del homelab. El segundo servidor, apagado.
Una infraestructura más simple, más fácil de auditar, más fácil de mantener. Y en un estado que, por fin, coincide con lo que tenía en la cabeza desde el principio.
Esta es la última entrega de la serie sobre infraestructura y seguridad. Los artículos anteriores cubren la auditoría de seguridad, la interpretación de resultados, el hardening y la automatización — todo disponible en el blog.