Headscale
Trucos, líos y soluciones varias para cuando Headscale decide hacerse el interesante.
- Cambiar direcciones IP asignadas a los nodos en Headscale
- Error DNS al usar Tailscale con Headscale
- Headscale v0.26 – Consideraciones tras la actualización
Cambiar direcciones IP asignadas a los nodos en Headscale
Introducción
Modificar la IP de un nodo en Headscale puede ser útil para tener un orden lógico o asignar direcciones específicas según el uso. Esto se puede hacer directamente desde la base de datos SQLite que usa Headscale.
Pasos para cambiar la IP
1. Parar Headscale
Con Docker:
docker-compose down
Con systemd:
sudo systemctl stop headscale
2. Entrar en la base de datos
sudo sqlite3 /ruta/a/la/base/de/datos/db.sqlite
3. Cambiar la IP de un nodo
Consulta SQL genérica:
update nodes set ipv4 = 'nueva-ipv4' where ipv4 = 'ip-actual';
Ejemplo concreto:
update nodes set ipv4 = '100.64.0.10' where ipv4 = '100.64.0.14';
4. Salir de SQLite
.quit
5. Volver a levantar Headscale
Con Docker:
docker-compose up -d
Con systemd:
sudo systemctl start headscale
6. Actualizar los clientes
Es recomendable que los clientes se reconecten para recibir la nueva IP. Puedes apagar y encender Tailscale en cada dispositivo.
Referencias
Error DNS al usar Tailscale con Headscale
Esto pasa cuando usas Tailscale (con servidor Headscale autohospedado) en Linux y al hacer tailscale status ves este tipo de error en el health check:
# Health check:
# - running /usr/sbin/resolvconf -m 0 -x -a tailscale: Failed to resolve interface "tailscale": No such device
# - Tailscale failed to set the DNS configuration of your device: running /usr/sbin/resolvconf -m 0 -x -a tailscale: Failed to resolve interface "tailscale": No such device
Causa
Tailscale espera que /etc/resolv.conf sea un enlace simbólico a systemd-resolved, pero a veces no lo es. Si ese enlace no está bien, no puede gestionar la configuración DNS correctamente y da ese error.
Solución
Forzar el enlace correcto:
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo systemctl restart tailscaled
Después de eso, el error desaparece y vuelve a funcionar el estado DNS como toca.
Fuente original
Esto está documentado en la propia página de Tailscale, en la sección de problemas comunes con DNS en Linux:
Headscale v0.26 – Consideraciones tras la actualización
Introducción
Notas sobre el cambio a Headscale v0.26.0 y los ajustes necesarios tras el salto a Policy v2. Este artículo recoge los dos puntos críticos que rompían la configuración previa: base_domain y los identificadores de usuario.
Requisitos previos
- Tener ya configurado Headscale con una versión anterior funcionando.
- Usar Caddy como proxy inverso con TLS (por eso no se usan las opciones de TLS internas de Headscale).
- Haber actualizado a la versión 0.26.0 o superior.
Cambios importantes en Headscale 0.26.0
Usuarios con @ obligatorio en Policy v2
Con la nueva implementación de políticas (Policy v2), todos los identificadores de usuario deben contener un @. Si no lo tienen, Headscale lanza un error como este:
"Invalid Owner 'xxx'. An alias must be one of the following types..."
También puedes ver este error ejecutando:
docker logs headscale # o el nombre del contenedor que uses
Ejemplo del policy.json antes (v1):
{
"tagOwners": {
"tag:admin": ["usuario1"],
"tag:srvadmin": ["usuario1"]
},
"acls": [
{
"action": "accept",
"src": ["tag:admin"],
"dst": ["*:*"]
},
{
"action": "accept",
"src": ["tag:srvadmin"],
"dst": [
"100.64.0.35:15134",
"100.64.0.35:13515",
"100.64.0.35:57000",
"100.64.0.35:5134"
]
}
]
}
Y después (v2):
{
"tagOwners": {
"tag:admin": ["usuario1@midominio.local"],
"tag:srvadmin": ["usuario1@midominio.local"]
},
"acls": [
{
"action": "accept",
"src": ["tag:admin"],
"dst": ["*:*"]
},
{
"action": "accept",
"src": ["tag:srvadmin"],
"dst": [
"100.64.0.35:15134",
"100.64.0.35:13515",
"100.64.0.35:57000",
"100.64.0.35:5134"
]
}
]
}
Para ver los usuarios válidos ya creados:
headscale users list
Migración de Policy v1 a v2 (pasos seguidos)
Esto fue lo que se hizo para realizar la migración correctamente:
-
Iniciar Headscale 0.26.0 con la variable de entorno
HEADSCALE_POLICY_V1=1oHEADSCALE_POLICY_V1: '1'activada.-
Se puede confirmar que ha funcionado si aparece este mensaje al arrancar:
Using policy manager version: 1
-
-
Volcar la política actual a un archivo:
headscale policy get > policy.json -
Editar
policy.jsony migrarlo manualmente al formato v2.-
Se puede comprobar si hay errores con:
headscale policy check --file policy.json
-
-
Cargar la política migrada:
-
Si estás usando Headscale en contenedor Docker, el archivo debe estar en una ruta accesible desde dentro del contenedor. Por ejemplo:
- './Headscale:/etc/headscale' -
En ese caso, el comando sería:
hs policy set --file /etc/headscale/policy.jsonDonde
hses un alias que apunta a:docker exec Headscale headscale
-
-
Reiniciar Headscale sin la variable
HEADSCALE_POLICY_V1.-
Si todo va bien, el mensaje será:
Using policy manager version: 2
-
base_domain no puede coincidir con server_url
Otro breaking change relevante es que base_domain no puede ser igual (ni estar contenido) en el server_url. Si coinciden, MagicDNS deja de funcionar o se comporta de forma errática.
Ejemplo incorrecto:
server_url: https://headscale.midominio.local
base_domain: midominio.local
Ejemplo correcto:
server_url: https://headscale.midominio.local
base_domain: redprivada.lan
En este caso se usó un dominio inventado, corto y sin registrar: redprivada.lan.
Errores comunes o decisiones importantes
- Si olvidaste poner
@a los usuarios, el error no es muy claro. Hay que revisar elpolicy.jsony asegurarse de que todos los identificadores lo llevan. - Aunque el
config-example.yamltrae bloques de Let's Encrypt, se ignoraron porque ya se gestiona TLS con Caddy. - Puedes registrar un dominio personalizado si lo ves útil, pero por ahora solo se usa como base de resolución DNS local.
- La migración de v1 a v2 puede hacerse sin sobresaltos si se siguen los pasos indicados, especialmente si estás usando Docker.
Resumen breve
- Todos los usuarios deben tener
@en su identificador. base_domainno puede coincidir conserver_url.- MagicDNS depende de que estos dos valores estén bien puestos.
- La política ahora se valida al cargar, no en tiempo de ejecución.
- La migración a Policy v2 se puede hacer conservando primero la configuración previa.
- Si usas Docker, asegúrate de que el archivo esté en una ruta montada dentro del contenedor.
Notas personales
Anotar bien estos dos cambios porque son minas antipersona: si se olvidan, te explota la configuración en la cara sin piedad.