Headscale

Trucos, líos y soluciones varias para cuando Headscale decide hacerse el interesante.

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:

Tailscale – Linux DNS

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


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:

  1. Iniciar Headscale 0.26.0 con la variable de entorno HEADSCALE_POLICY_V1=1 o HEADSCALE_POLICY_V1: '1' activada.

    • Se puede confirmar que ha funcionado si aparece este mensaje al arrancar:

      Using policy manager version: 1
      
  2. Volcar la política actual a un archivo:

    headscale policy get > policy.json
    
  3. Editar policy.json y migrarlo manualmente al formato v2.

    • Se puede comprobar si hay errores con:

      headscale policy check --file policy.json
      
  4. 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.json
      

      Donde hs es un alias que apunta a:

      docker exec Headscale headscale
      
  5. 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


Resumen breve


Notas personales

Anotar bien estos dos cambios porque son minas antipersona: si se olvidan, te explota la configuración en la cara sin piedad.


Referencias