Headscale + Headplane (GUI): Tu propio servidor Tailscale autohospedado
Introducción
Este artículo documenta el despliegue de Headscale como servidor de control autohospedado para redes tipo Tailscale, junto con Headplane como interfaz gráfica de administración.
Headscale es una implementación open‑source del backend de Tailscale que permite operar una red VPN en malla basada en WireGuard sin depender de servicios externos. Todo el control —usuarios, nodos, claves, políticas y DNS— reside en infraestructura propia.
El modelo de red es mesh: los dispositivos intentan comunicarse directamente entre sí, recurriendo a un relay (DERP) únicamente cuando no es posible establecer conexión directa. Esto reduce latencia, evita tráfico innecesario y mantiene el control del plano de datos.
Headplane complementa a Headscale aportando una GUI web moderna para la gestión diaria: visualización de nodos, usuarios, ACLs, DNS, políticas y estado general del tailnet. No sustituye al CLI de Headscale, pero reduce fricción operativa y errores humanos.
Configuración con Docker
El despliegue se realiza íntegramente mediante contenedores. El archivo docker-compose.yml, junto con el resto de configuraciones asociadas, se mantiene versionado en Gitea:
La separación entre servicios permite actualizar Headscale o Headplane de forma independiente y facilita la trazabilidad de cambios.
Estructura de directorios esperada
La estructura del directorio está pensada para aislar configuraciones y datos persistentes, evitando mezclas entre componentes:
.
├── data
│ └── ...
├── docker-compose.yml
├── Headplane
│ └── config.yaml
└── Headscale
├── acl.hujson
└── config.yaml
Los volúmenes se montan utilizando el UID/GID del usuario normal del sistema (1000:1000), simplificando permisos y evitando dependencias de root dentro de los contenedores.
Configuración de Headplane
La configuración de Headplane se gestiona mediante su propio archivo config.yaml, disponible en el repositorio:
config.yaml de Hadplane en Gitea
Headplane actúa como capa de presentación y orquestación visual sobre la API de Headscale. Para ello requiere una API Key válida, que se genera desde el propio Headscale.
La interfaz web de Headplane puede protegerse sin problema tras un proxy con autenticación (por ejemplo, Authentik), añadiendo control de acceso sin interferir con el funcionamiento interno de Headscale.
Configuración de Headscale
El archivo principal de configuración de Headscale define el comportamiento global del servidor: URLs, DNS, política, DERP, almacenamiento y autenticación.
Config disponible en:
config.yaml de Headscale en Gitea
Las ACLs se mantienen separadas en acl.hujson, permitiendo versionarlas y modificarlas sin tocar el núcleo de configuración.
Pasos iniciales
Una vez definida la estructura y las configuraciones:
- Levantar el stack de contenedores:
docker-compose up -d
- Generar una API Key para consumo externo (Headplane u otros clientes):
docker exec Headscale headscale apikeys create
- Añadir la API Key generada al
docker-compose.yml(servicio Headplane) y reiniciar los contenedores:
docker-compose restart
- Acceder a la interfaz web de Headplane:
http://<IP_DEL_SERVIDOR>:3170
- Crear el primer usuario en Headscale:
docker exec Headscale headscale users create <nombre>
A partir de este punto, los nodos pueden empezar a autenticarse y unirse al tailnet.
Consideraciones importantes (Headscale 0.26+)
Desde la versión 0.26, Headscale introduce cambios relevantes que afectan a despliegues existentes y nuevos:
- Los identificadores de usuario deben incluir
@(por ejemplo,usuario@dominio). base_domainno puede coincidir conserver_url.- Las ACLs clásicas quedan obsoletas: es obligatorio migrar a Policy v2.
La migración y los cambios asociados se documentan en:
Consideraciones tras la actualización a la v0.26
Ignorar estos puntos suele derivar en errores de autenticación, problemas de registro de nodos o políticas que no se aplican.
Conclusión
La combinación de Headscale y Headplane permite operar una VPN mesh moderna, controlada íntegramente en infraestructura propia y con una capa gráfica que simplifica la gestión diaria. La separación clara entre contenedores, configuraciones y políticas facilita el mantenimiento, las actualizaciones y la evolución futura del entorno sin introducir acoplamientos innecesarios.