La foto (por Denys Nevozhai @dnevozhai) muestra una autopista en Shanghai, China
Cuando comencé a construir mi homelab estaba satisfecho con poder consumir mis servicios desde mi LAN, para eso
me bastó con instalar pihole, levantar un load balancer service en k3s apuntando a mi pod de pihole en el puerto 53,
configurar mi router para usar la ip del load balancer como unico servidor de DNS y crear un registro A en pihole
apuntando home.lan a la ip de otro load balancer que conecta con un pod de HAProxy que se encarga de hacer un
host-based routing a los distintos servicios de mi cluster. Por último, creé varios registros CNAME como alias del
home.lan para los demas servicios.
Toda la ruta que puse de forma casual y resumida en el párrafo anterior, la pienso explicar más a detalle en un futuro artículo, pues hay varios detalles interesantes
Fue suficiente y funcionó muy bien hasta que quise más.
Nuevas ambiciones
No había pasado ni una semana completa desde que dejé configurado el acceso local a los servicios de mi cluster, cuando ya empecé e querer más cosas: acceder a mi cluster desde fuera de mi LAN, pero en forma segura, claro…
Asi que me puse a pensar y a investigar cual sería la mejor manera de lograrlo. La manera mas fácil sería abrir un puerto en mi router y permitir el tráfico entrante, pero me encontré muchas advertencias, historias de terror, peligros, y más. Y claro, nadie quiere jugar con la posibilidad de dejar una puerta abierta al cochino mundo del internet público.
De igual forma pensé que tal vez si lo hacía con las precauciones necesarias, las mejores prácticas, firewall, iptables, etc, quizás podría hacer una pruebita e ir evaluando. Al principio expondría algo muy simple e inocuo, intentaría hacer auditorias de seguridad, etc… Lo ví posible por un momento, pero aun sin concretar nada, todo en pensamientos y con dudas y temores.
Afortunadamente, no tuve que tomar esa decisión, pues mi proveedor de servicios de internet (Starlink), usa un tipo de NAT que no permite el enrutamiento desde la internet publica. Este tipo de NAT se llama CGNAT (Carrier-grade NAT), y básicamente comparte una misma ipv4 pública para muchos clientes. Los detalles de CGNAT dan para un articulo propio asi que dejémoslo así.
Hub and Spoke
En ese momento empecé a evaluar alternativas, y tras mucha lectura y evaluación, decidí armar una VPN para acceder de forma segura a mis servicios desde cualquier red fuera de mi LAN. Por supuesto, esto no quita que seguía teniendo el problemita del CGNAT, pero si me abrió la puerta a una interesante topología de red: Hub and Spoke (Centro y radios, como la rueda de una bicicleta).
En esta topología, hay una maquina al centro que recibe las conexiones entrantes de todos los participantes de la red y actúa como centro de distribución y enrutamiento de los paquetes de red. Aquí el punto interesante es que el centro recibe conexiones entrantes. Ahi está la clave para superar el CGNAT. Mi homelab no necesitaría recibir conexiones, solo necesitaría conectarse al Hub.
Hub and Spoke… and site
La verdad que la topología a la que llegué, creo que sería una combinación de Hub and Spoke y Point to Site, ya que existe un hub central y radios, pero uno de los radios es mi homelab completo, o sea un “site”, por eso la topología se podría considerar una combinación de ambos.
Aqui quiero poner un diagramita de la topología, pero por ahora te lo debo!
Para implementar esta topología, decidí usar Wireguard, ya que es liviano y seguro. Hace una sola cosa y la hace bien. He aquí los pasos que tomé para lograrlo:
1. La VPS
Primero, me vi en la necesidad de contratar una VPS para poder tener una ip pública.
Inicialmente, levanté una pequeña máquina virtual en OCI (Oracle cloud). Tienen un Free tier forever bastante
interesante en donde logré tener una maquina corriendo Wireguard detrás de una ip pública de forma totalmente
gratuita.
Esto funcionó muy bien un buen tiempo, pero un día tuve problemas pues Oracle al parecer me cerró la VPS y me
dejó con acceso limitado a mi infraestructura un rato, lo que me hizo optar por cambiarme a Vultr, donde pago
4 dólares mensuales por una VPS muy pequeñita, pero tengo la confianza de que no me la van a bajar por ser free tier
En esta VPS entonces, instalé Wireguard y lo configuré para ser el centro en la topología. El Hub. La idea era que todas las máquinas se conectaran a este centro, y desde aquí, se enrutaran las comunicaciones, es decir, la VPS no iniciaría ninguna conexión proactivamente, sino que recibiría conexiones entrantes y enrutaría los paquetes de red entre los distintos participantes de la VPN.
Detalles de la configuración los puedo compartir en un artículo más detallado
2. Los clientes (spokes)
Cada cliente instala wireguard. En mi laptop personal, en mi teléfono, etc.
Hay aplicaciones disponibles para Mac, iPhone, Android y Windows. La configuracion es relativamente sencilla, se crea un par de llaves publico y privada, se registra la llave publica del cliente en el hub, se asignan ips de la subnet creada para la VPN, y se especifica si queremos usar un DNS distinto para cuando estamos conectados a la VPN.
En mi caso, apunté el DNS a la ip del load balancer de mi pihole, lo que me permite usar los mismos hostnames que uso cuando estoy en mi LAN. El resultado es hermoso ✨
3. El cliente homelab (el “site” en la topología)
El spoke correspondiente al homelab merece un tratamiento un poco mas especial, ya que debe configurar iptables para enrutar los paquetes correctamente a los distintos destinos: Al servidor de DNS (pihole), al pod de HAProxy (host based routing reverse proxy) y también permitir conectar por ssh a los servidores del homelab.
Además, al ser este el punto de entrada a mi red local, aquí se descartan los paquetes que vayan dirigidos a cualquier otro lado, como medida extra de seguridad.
4. PKI (Public Key Infrastructure)
Durante un tiempo no vi necesidad de usar SSL para mis comunicaciones en la LAN o usando la VPN, ya que bueno, en la LAN se goza de una seguridad natural al estar en una red privada, y la VPN provee un excelente grado de seguridad con su encriptación con llave publica y privada, pero esto cambió cuando instalé Vaultwarden (una implementación open source compatible con la api de Bitwarden para manejo de contraseñas y datos personales sensibles), pues el cliente de Bitwarden exige que la url de la API de Bitwarden (o Vaultwarden en mi caso), sea por https. Por lo tanto, opté por crear mi propia infraestructura de llave publica aprovechando los componentes de k8s, pero eso también es material para otro artículo, ya que también es muy extenso y lleno de detalles.
Ahora que esto ya está funcionando y ha pasado la prueba del tiempo y el uso, lo puedo contar así livianamente, pero la verdad es que hubo muchas noches de dormir poco ajustando los detalles para que esto funcionara correctamente, pero el resultado vale la pena. Ahora tengo acceso a mis servicios desde cualquier red sin necesidad de usar hostnames diferentes, y además esto me dejó el camino allanado para el siguiente paso que fue permitir el acceso público a ciertos servicios de mi homelab, como por ejemplo este blog, pero eso lo dejaremos para otra publicación.
Apreciado lector, espero hayas encontrado algo de utilidad en este artículo, un momento interesante o quizás algo de entretención. Pienso que siempre estaré revisando los artículos ya publicados y los iré enriqueciendo a medida que se me vayan ocurriendo mejores maneras de expresar las ideas. Nos vemos en otra publicación!