La mascota de NordBastion, un oso polar, de pie en un salón de piedra nórdico en penumbra con una pata apoyada en un obelisco de piedra angular rúnica tallada, un anillo holográfico cian y flotante de llaves suspendido sobre él, y cinco glifos de dispositivos resplandecientes — un portátil, un teléfono, una tableta, una torre de servidor y un globo terráqueo — enlazados directamente entre sí en una malla cian brillante en lo alto, mientras tenues líneas punteadas de llaves caen del anillo hacia cada dispositivo, un rack de servidores y una ventana arqueada iluminada por la aurora detrás de él
Guía práctica · Redes privadas·19 min de lectura · 50 min prácticos

Su propio servidor de control.
El mapa es lo que merece la pena poseer.

Una VPN de malla necesita a alguien que reparta las claves. Con Tailscale, ese alguien es una empresa; con WireGuard puro, es usted, a mano, para siempre. Headscale es la tercera respuesta: el mismo cliente de código abierto, hablando con un servidor de coordinación en una máquina que usted alquila de forma anónima. Seis pasos hacia un tailnet cuyo mapa de dispositivos, reglas de acceso y relés de respaldo son enteramente suyos — Headscale detrás de Caddy, ACL por escrito, MagicDNS apuntando a su propio resolver, un enrutador de subred, un nodo de salida y un DERP integrado. La máquina cuesta $3.90 al mes. Probado en Debian 12.

Los seis pasos
  1. 01

    Elegir

    WireGuard, Tailscale y Headscale

  2. 02

    Aprovisionar

    Tres nombres fijados antes del arranque

  3. 03

    Desplegar

    Headscale, Caddy, una sola configuración

  4. 04

    Registrar

    Usuarios, claves de preautenticación, clientes

  5. 05

    Enrutar

    Subredes, nodo de salida, ACL

  6. 06

    Mantener

    DERP, copias de seguridad, actualizaciones

Antes de empezar · Qué es un plano de control

Nadie puede leer el tráfico. Alguien sigue poseyendo el mapa.

WireGuard es deliberadamente incompleto. Es un túnel pequeño, rápido y auditable entre dos claves públicas, y no tiene ninguna opinión sobre cómo esas claves se encuentran entre sí. Esa omisión es la razón por la que el protocolo es tan bueno como es — y también es la razón por la que una red WireGuard de quince dispositivos es una hoja de cálculo. Cada par necesita la clave pública y la dirección actual de todos los demás pares, y cada portátil que se mueve entre una oficina, un tren y un hotel invalida parte de esa hoja de cálculo.

Una VPN de malla es la respuesta a ese problema concreto, y merece la pena precisar su forma exacta, porque de ella depende en qué está confiando. El plano de datos permanece exactamente igual que siempre: cada dispositivo genera su propio par de claves localmente, se queda con la mitad privada, y cifra directamente hacia sus pares. Encima se sitúa un plano de control — un pequeño servicio que recopila claves públicas y puntos de conexión, entrega a cada dispositivo la lista de pares con los que puede hablar, y ayuda a que dos dispositivos detrás de routers hostiles se encuentren. Ese servicio nunca guarda una clave privada ni ve un solo byte en texto plano.

Lo que sí posee es el mapa, y el mapa es más interesante de lo que la mayoría supone. El nombre de cada dispositivo y el de cada usuario. Todas las claves públicas. La dirección pública desde la que se conecta cada dispositivo en este preciso momento, que es un registro en vivo de dónde están físicamente su portátil y su teléfono. Las horas a las que cada dispositivo se conecta y se desconecta, que describen su día. Y la política que decide quién puede llegar a qué, que describe su organización. Nada de eso requiere mala fe por parte de nadie; es sencillamente para lo que sirve un servidor de coordinación.

Hay una propiedad más que importa más que los metadatos. El plano de control es lo que distribuye las claves, así que también es lo que podría añadir una. Un servidor de control comprometido, o coaccionado, puede decirle a sus dispositivos que una máquina nueva es un miembro legítimo de la red — y sus dispositivos, haciendo exactamente lo que fueron diseñados para hacer, cifrarán hacia ella. Tailscale se toma esto lo bastante en serio como para haber construido una función de firma que lo evita. Autoalojarse resuelve el mismo problema desde la otra dirección: la parte que podría hacerlo es usted. Cuatro configuraciones, y lo que cada una revela en realidad:

Propiedad WireGuard manual Tailscale, alojado Headscale en su VPS Headscale + su propio DERP
Quién puede leer el contenidoNadie salvo los paresNadie salvo los paresNadie salvo los paresNadie salvo los pares
Quién posee el mapa de dispositivosUsted, en un archivo de textoUna empresa, en su jurisdicciónUsted, en su VPSUsted, en su VPS
Quién ve desde dónde se conectan los dispositivosSolo los propios paresEl servidor de coordinación, de forma continuaSu servidor, de forma continuaSu servidor, de forma continua
Quién retransmite cuando falla un enlace directoNadie — el enlace, sencillamente, fallaLa flota de relés del proveedorSiguen siendo los relés del proveedor, por defectoSu relé, en su centro de datos
Añadir el vigésimo dispositivoDiecinueve ediciones de configuraciónUn comandoUn comandoUn comando
Elíjalo cuandoPocos dispositivos, ninguno itineranteQuiere cero operaciones y acepta el mapaQuiere el mapa y puede ocuparse de una máquina pequeñaQuiere el mapa, y también la ruta de respaldo

La primera columna no es un hombre de paja. Para un puñado estático de servidores, un WireGuard escrito a mano es, de verdad, la mejor solución de ingeniería, y es un servicio menos que parchear. Esta guía trata sobre el punto en el que la hoja de cálculo deja de tener gracia.

Paso 01 · Elegir

¿Necesita un plano de control? Cuente los dispositivos que se mueven.

Hay tres respuestas honestas a "quiero que mis máquinas se alcancen entre sí de forma privada", y solo una de ellas es esta guía. WireGuard puro es la más pequeña: un módulo del kernel, un archivo de configuración por cada par, ningún demonio más allá de la interfaz, nada que mantener actualizado salvo el sistema operativo. Si sus dispositivos son servidores con direcciones fijas y puede contarlos con los dedos de una mano, deténgase aquí y lea la guía de WireGuard en su lugar. Acabará con menos software y una lista más corta de cosas que pueden romperse.

Tailscale es la más grande: el mismo WireGuard por debajo, más un servicio de coordinación, un sistema de traspaso de NAT que funciona detrás de casi cualquier cosa, una flota de relés en varios continentes, una consola web, inicio de sesión único y un contrato de soporte. Es un software genuinamente excelente, y el nivel gratuito cubre un hogar con holgura. El precio no es dinero: es que el mapa de todos los dispositivos que posee, y el registro de desde dónde se conecta cada uno, vive en la base de datos de una empresa.

Headscale es la tercera respuesta, y es más limitada que las otras dos: una reimplementación de código abierto del servidor de coordinación, gestionada por usted y a la que habla el mismo cliente oficial. Conserva la automatización y el traspaso de NAT; a cambio asume un pequeño servicio que operar, un conjunto de funciones parcial y actualizaciones que hay que leer con atención. Nadie debería fingir que eso sale gratis. Compra exactamente una cosa, y es la que le importa a este sitio: nadie más posee el mapa.

El umbral de los cinco dispositivos

La configuración manual de WireGuard crece con el cuadrado del tamaño de la flota: cuatro pares son seis enlaces, diez pares son cuarenta y cinco, veinte pares son ciento noventa. Añada un portátil itinerante, cuyo punto de conexión cambia con cada red a la que se une, y el mantenimiento deja de ser ocasional. En la práctica, el punto de cruce ronda los cinco dispositivos, o el primer dispositivo que cambia de red a diario, o la primera regla de acceso que no se puede expresar como "todos pueden llegar a todo".

Una cosa más que decidir ahora y no después, porque cambia lo que instala: si esta red es solo para usted, o si se le van a unir otras personas. Un tailnet de una sola persona puede quedarse completamente abierto por dentro sin que pase nada malo. Un tailnet con un colega, un contratista o un familiar necesita reglas de acceso por escrito desde la primera semana — el paso 05 — y necesita que los usuarios estén separados en lugar de que todos compartan un mismo inicio de sesión. Decidir esto de antemano cuesta un párrafo; hacerlo a posteriori cuesta una tarde entera.

Paso 02 · Aprovisionar

Tres nombres, decididos antes del primer arranque. Los tres son difíciles de cambiar.

Encargue la máquina primero. En el panel: Order → VPS → Sentinel, imagen Debian 12, en el bastión en el que quiera que viva el mapa — Helsinki, Stockholm, Oslo o Reykjavík. No hace falta ninguna dirección de correo para abrir la cuenta, y la factura se salda en Monero, Bitcoin, Lightning o cualquier otro activo admitido. Elija el bastión más cercano a la mayoría de sus dispositivos si también piensa ejecutar el relé del paso 06; la latencia hasta un relé es la latencia de cada conexión que transporta.

Después, aplique la lista de verificación de endurecimiento de la primera hora — SSH solo con clave en un puerto distinto del habitual, actualizaciones desatendidas, un cortafuegos que deniega por defecto. Todo lo que sigue asume una máquina que todavía no es de otra persona, y esta vale más que la mayoría: es la máquina que decide qué claves son de confianza en todos los dispositivos que posee.

Decida estas tres cosas antes de que se registre nada

Cada dispositivo incorpora las tres a su estado en el momento en que se une, así que cambiar una después significa volver a registrar toda la flota a mano. Uno: la URL del servidor de control — la dirección HTTPS pública exacta a la que marcará cada cliente, esquema y nombre de host incluidos. Dos: el sufijo DNS del tailnet, el dominio que MagicDNS resolverá internamente; debe ser uno que usted controle, y no puede ser padre ni hijo del propio nombre de host del servidor de control, que es el fallo de primer arranque más frecuente con diferencia. Tres: los rangos de direcciones que reparte el tailnet, por convención el bloque de NAT de grado operador 100.64.0.0/10 para IPv4 y un /48 de alcance único local para IPv6; deje los valores por defecto salvo que ya choquen con una red que utilice.

Un ejemplo resuelto, y la forma que conviene copiar: el servidor de control responde en vpn.example.com, el sufijo del tailnet es ts.example.com, y los rangos se quedan en sus valores por defecto. Fíjese en que el sufijo es hermano del nombre de host de control, no su padre — vpn.example.com y ts.example.com comparten un dominio registrable, pero ninguno contiene al otro. Apunte un registro A — y un AAAA si quiere que sea alcanzable por IPv6 — hacia la máquina, y deje que se propague antes de empezar, porque el proxy inverso intentará obtener un certificado para ese nombre la primera vez que arranque.

Después, escriba las reglas del cortafuegos mientras todavía no hay nada escuchando. El servidor de control es, por necesidad, un punto de conexión HTTPS público: todos los dispositivos, en cualquier red, tienen que poder llegar hasta él. El puerto UDP solo hace falta si piensa ejecutar su propio relé en el paso 06, y es más fácil abrirlo ahora que depurar su ausencia más adelante.

ufw default deny incoming
ufw allow 47222/tcp                  # administrative SSH, moved
ufw allow 80/tcp                     # ACME HTTP-01 challenge
ufw allow 443/tcp                    # the control server, and DERP over HTTPS
ufw allow 3478/udp                   # STUN, only if you run your own relay
ufw enable
ufw status numbered

Instale Docker desde el repositorio oficial en lugar del paquete de la distribución, para que Compose v2 esté presente y actualizado. Luego cree los dos directorios que van a contener todo lo que merece la pena respaldar — uno para la configuración, otro para el estado — y resista la tentación de meter cualquier otra cosa en ellos.

curl -fsSL https://get.docker.com | sh
docker compose version

install -d -m 0750 /srv/headscale/config
install -d -m 0750 /srv/headscale/data
cd /srv/headscale
Paso 03 · Desplegar

Dos contenedores y un archivo. Fije la versión, siempre.

Headscale y Caddy, y nada más. Headscale escucha en HTTP simple dentro de la red de Docker; Caddy termina el TLS, obtiene el certificado en el primer arranque y lo renueva sin que nadie se lo pida. El listener de métricas se queda en localhost, porque es una superficie de depuración interna, no pública.

Una regla antes del archivo: fije la imagen a una versión exacta. Headscale es software anterior a la versión 1.0, que ha renombrado claves de configuración y subcomandos de la CLI entre versiones menores más de una vez. Una etiqueta flotante convierte un reinicio rutinario de contenedor en una interrupción de un servicio cuyo trabajo es dejarle llegar a todo lo demás.

/srv/headscale/docker-compose.yml

services:
  headscale:
    image: docker.io/headscale/headscale:0.26            # pin it; never :latest
    container_name: headscale
    command: serve
    volumes:
      - ./config:/etc/headscale
      - ./data:/var/lib/headscale
    ports:
      - "3478:3478/udp"                                  # STUN, for your own DERP
    restart: unless-stopped

  caddy:
    image: caddy:2-alpine
    container_name: caddy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
    restart: unless-stopped

volumes:
  caddy_data:

/srv/headscale/Caddyfile

vpn.example.com {
    reverse_proxy headscale:8080
}

Eso es toda la configuración del proxy. Caddy habla HTTP/2 y actualiza las conexiones de larga duración sin que nadie se lo pida, lo cual importa aquí porque cada cliente mantiene una abierta para recibir actualizaciones del mapa. Tome el archivo de configuración de ejemplo que se incluye con la versión que ha fijado, y edítelo en lugar de escribir uno desde cero — el archivo es largo, la mayor parte son valores por defecto sensatos, y las claves que importan son estas:

/srv/headscale/config/config.yaml — the lines that matter

server_url: https://vpn.example.com          # exactly what clients will dial
listen_addr: 0.0.0.0:8080                    # inside the Docker network only
metrics_listen_addr: 127.0.0.1:9090          # debug surface, keep it local

prefixes:
  v4: 100.64.0.0/10
  v6: fd7a:115c:a1e0::/48

noise:
  private_key_path: /var/lib/headscale/noise_private.key

database:
  type: sqlite                               # postgres for a large fleet
  sqlite:
    path: /var/lib/headscale/db.sqlite

dns:
  magic_dns: true
  base_domain: ts.example.com                # NOT a parent or child of server_url
  nameservers:
    global:
      - 1.1.1.1                              # replaced by your own in step 05

Levántelo, y luego lea el registro en lugar de suponer. Un primer arranque que no consigue obtener un certificado, o que rechaza el sufijo DNS porque se solapa con el nombre de host del servidor, lo indica con claridad y se detiene.

docker compose up -d
docker compose logs -f headscale

# From your laptop — a control server that is up answers this:
curl -s https://vpn.example.com/health

El primer arranque genera el material de la clave privada en /srv/headscale/data. Cópielo a un lugar seguro ahora mismo, antes de que se registre un solo dispositivo, y otra vez después del primer registro: perder esa clave significa que todos los dispositivos rechazan el servidor en el que confiaban, y la única reparación posible es volver a registrarlos todos a mano. El paso 06 convierte esa copia en una copia de seguridad de verdad.

Paso 04 · Registrar

Un usuario, una clave, un cliente. Después, compruebe si la conexión fue directa.

El comando headscale vive dentro del contenedor, así que toda acción administrativa es un docker exec. Cree primero un usuario — un usuario es quien posee los dispositivos y la unidad a la que se refieren las reglas de acceso, así que dele el nombre de una persona o un rol, no el de una máquina.

hs() { docker exec -it headscale headscale "$@"; }

hs users create alice
hs users list                      # note the numeric id — newer releases want it

# A single-use key that expires in an hour is the right default.
hs preauthkeys create --user 1 --expiration 1h

Luego levante el cliente oficial en el dispositivo, apuntándolo a su servidor en lugar de al que trae por defecto. Este es un parámetro admitido oficialmente, no un truco — el cliente es de código abierto, y el servidor de inicio de sesión es un parámetro más.

# On the device (Debian/Ubuntu shown; every platform has an equivalent):
curl -fsSL https://tailscale.com/install.sh | sh

sudo tailscale up \
  --login-server https://vpn.example.com \
  --auth-key <the-key-you-just-created>

tailscale status
tailscale ip -4

Sin una clave de preautenticación, el cliente muestra en su lugar una URL; al visitarla aparece un comando de registro para ejecutar en el servidor, que es la vía interactiva y resulta cómoda para un dispositivo que tiene delante. En cualquier caso, haga el segundo dispositivo antes de celebrar nada — una malla de uno no demuestra nada. Hágale ping por su dirección de tailnet, y luego lea con atención el resultado del estado:

hs nodes list

# On a client, the word after the peer name is the one that matters:
tailscale status
#   100.64.0.2  laptop  alice  linux  active; direct 203.0.113.9:41641
#                                              ^^^^^^ direct, not relay

tailscale netcheck                 # why it chose what it chose

direct significa que los dos dispositivos se han encontrado y el tráfico va de igual a igual. relay significa que pasa por un servidor DERP, lo cual funciona bien pero añade latencia y pone una tercera máquina en el camino — y, por defecto, esa máquina no es suya. El paso 06 se encarga de resolver cuál de las dos es.

Teléfonos, tabletas y el rodeo de Apple

Los equipos de escritorio usan un parámetro de línea de comandos. Android expone el servidor personalizado dentro de la app, detrás del número de versión en su pantalla de ajustes. Las plataformas de Apple no tienen ningún campo dentro de la app: se instala un pequeño perfil de configuración que fija la URL del servidor de control antes de iniciar sesión, lo cual es tedioso una vez y permanente después. Dos cosas ahorran tiempo. Consulte la página por cliente de la documentación de Headscale en lugar de adivinar, porque el proceso en Apple ha cambiado más de una vez. Y cierre primero la sesión de la app en el propio servicio de Tailscale — una app que ya mantiene una sesión ahí a menudo se niega a aceptar un servidor distinto hasta que se cierra sesión, o se reinstala.

Dos hábitos que conviene adoptar de inmediato. Use claves de preautenticación de un solo uso y de corta duración para las personas, y claves reutilizables o efímeras solo para la automatización que de verdad las necesita — una clave efímera registra un dispositivo que se elimina a sí mismo cuando se desconecta, lo cual es exactamente lo correcto para un ejecutor de CI y exactamente lo incorrecto para un portátil. Y decida ya su postura sobre la caducidad de las claves: un dispositivo registrado lleva una fecha de caducidad, y un dispositivo cuya clave ha caducado deja de ser alcanzable hasta que alguien lo vuelve a autenticar. Eso es una función de seguridad en un portátil y un generador de interrupciones en un servidor sin pantalla a las tres de la madrugada. Compruebe cómo gestiona la caducidad su versión — los subcomandos se han movido — y configúrela deliberadamente para cada dispositivo, en lugar de descubrir el valor por defecto por las malas.

Paso 05 · Enrutar

Anunciado no es aprobado. Dos comandos, dos máquinas.

Un tailnet en el que cualquier dispositivo alcanza a cualquier otro ya es útil de por sí. Tres añadidos lo convierten en una red y no en un simple conjunto de túneles, y los tres comparten una característica con la que la gente tropieza: el cliente anuncia una capacidad, y el servidor debe aprobarla. Una ruta anunciada pero no aprobada, sencillamente, no existe — en silencio — y el síntoma es que se puede hacer ping al enrutador pero no a nada de lo que hay detrás.

Un enrutador de subred — ponga toda una LAN dentro del tailnet. Una máquina en una red doméstica o de oficina anuncia el rango de esa red; después, cualquier otro dispositivo llega a las impresoras, el NAS y las interfaces de administración que hay detrás sin necesidad de instalar nada más ahí. Active primero el reenvío en el kernel, o los paquetes se quedarán en el enrutador sin ningún mensaje de error.

# On the machine that sits inside the LAN:
echo 'net.ipv4.ip_forward = 1'          | sudo tee /etc/sysctl.d/99-ts.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-ts.conf
sudo sysctl -p /etc/sysctl.d/99-ts.conf

sudo tailscale up --login-server https://vpn.example.com \
  --advertise-routes=192.168.1.0/24 --accept-routes

# On the control server — approve it, or it does not exist.
# The subcommand moved between releases; check `hs nodes --help` first.
hs nodes list
hs nodes approve-routes --identifier 3 --routes 192.168.1.0/24

Un nodo de salida — envíe todo el tráfico a través del VPS. El mismo mecanismo con una ruta más amplia: un dispositivo que se anuncia como nodo de salida se ofrece a cargar con toda la conexión a internet de otro dispositivo. En una red de cafetería u hotel no confiable, eso es exactamente lo que se necesita, y es lo más parecido a una VPN personal que hay en esta guía.

# On the VPS that will do the exiting (forwarding must be on, as above):
sudo tailscale up --login-server https://vpn.example.com --advertise-exit-node

# Approve it on the control server, then on the laptop:
tailscale set --exit-node=100.64.0.1 --exit-node-allow-lan-access
tailscale set --exit-node=                    # turn it off again

Un nodo de salida no es una VPN comercial, y no debería venderse a sí mismo la idea de que lo es. Su dirección es solo suya y es estable, lo cual es excelente contra el Wi-Fi de la cafetería e inútil contra la correlación a largo plazo entre sitios — el equilibrio se explica en la guía principal. Tenga en cuenta también que puede ejecutar el nodo de salida en un segundo VPS más barato, y mantener el servidor de control completamente libre de tráfico retransmitido.

Reglas de acceso — escríbalas antes de que se una la segunda persona. La política por defecto es permitir todo, lo cual es correcto para un tailnet de una sola persona y deja de serlo en cuanto hay alguien más en él. La política es un pequeño documento HuJSON: grupos de usuarios, etiquetas para las máquinas, y una lista de reglas que dicen qué orígenes pueden llegar a qué destinos y por qué puertos. Apunte la configuración hacia el archivo, mantenga el archivo bajo control de versiones, y recargue después de cada edición.

{
  "groups": {
    "group:admin":     ["alice"],
    "group:contractor":["bob"]
  },
  "tagOwners": {
    "tag:server": ["group:admin"],
    "tag:exit":   ["group:admin"]
  },
  "acls": [
    // Admins reach everything.
    { "action": "accept", "src": ["group:admin"], "dst": ["*:*"] },

    // The contractor reaches one machine, on two ports, and nothing else.
    { "action": "accept", "src": ["group:contractor"],
      "dst": ["tag:server:22,443"] }
  ],
  "autoApprovers": {
    "routes":   { "192.168.1.0/24": ["tag:server"] },
    "exitNode": ["tag:exit"]
  }
}

Dos notas sobre ese archivo. El lenguaje de políticas es el de Tailscale, y Headscale implementa un subconjunto amplio y creciente de él, no todo — consulte la documentación de su versión antes de confiar en una regla poco habitual. Y dónde vive la política también se ha movido: las versiones más antiguas indicaban una ruta en la configuración de nivel superior; las más recientes la agrupan bajo una sección de política con un modo que también puede mantener las reglas en la base de datos. Ambas están documentadas; la que importa es la que trae la versión que ha fijado.

MagicDNS — nombres cortos, y su propio resolver en todas partes. Con MagicDNS activado, cada dispositivo responde a un nombre corto dentro del sufijo que eligió en el paso 02, así que ssh nas funciona desde cualquier lugar sin necesidad de un archivo hosts. La segunda mitad es la interesante: el servidor de control también envía una lista de servidores de nombres a cada cliente, lo que significa que el resolver que construyó en la guía del resolver DNS privado puede servir a su teléfono con datos móviles — filtrando, cacheando y sin registrar nada — mientras escucha en una dirección del tailnet que no es alcanzable desde internet en absoluto.

dns:
  magic_dns: true
  base_domain: ts.example.com
  override_local_dns: true          # beat whatever DHCP handed the device
  nameservers:
    global:
      - 100.64.0.5                  # your resolver, on the tailnet
Paso 06 · Conservar

Su propio relé, su propia copia de seguridad. Y actualizaciones leídas antes de aplicarlas.

El relé que se había olvidado de que estaba usando. Cuando dos dispositivos no pueden abrir una conexión directa — NAT simétrico en ambos extremos, un cortafuegos que se traga el UDP, un operador haciendo algo creativo — el tráfico recurre a un relé DERP. Sigue cifrado de extremo a extremo, así que el relé transporta texto cifrado. Lo que ve el relé es quién habla con quién, cuánto y cuándo. De fábrica, Headscale entrega a sus clientes el mapa público de relés, y esos relés los opera la empresa de la que se estaba alejando. Headscale incluye un relé integrado; activarlo pone ese respaldo en el mismo centro de datos nórdico que todo lo demás.

derp:
  server:
    enabled: true
    region_id: 999                  # custom regions live in the 900s
    region_code: "nb-hel"
    region_name: "Helsinki (self-hosted)"
    stun_listen_addr: "0.0.0.0:3478"
  urls:
    - https://controlplane.tailscale.com/derpmap/default   # remove for yours only
  auto_update_enabled: true
  update_frequency: 24h

Dejar el mapa público junto a su propia región es la opción práctica por defecto: los clientes prefieren el relé más cercano, así que un dispositivo en el mismo hemisferio usa el suyo, y uno al otro lado del mundo no queda varado detrás de un único salto nórdico. Quitar la URL pública hace que el tailnet sea estrictamente autocontenido, al precio de un peor respaldo para los dispositivos lejanos. Las dos opciones son defendibles; elija con conocimiento de causa, no por omisión.

Cuatro archivos, fuera de sitio, cifrados. La copia de seguridad es lo bastante pequeña como para resultar embarazoso no tenerla: la base de datos, el material de la clave privada, el archivo de configuración y el archivo de políticas. Juntos son un error de redondeo en cualquier factura de almacenamiento, y sin el material de claves, todos los dispositivos de la red rechazan el servidor. Envíelos a algún sitio que no sea esta máquina — idealmente una segunda jurisdicción, que es lo que cubre la guía de copias de seguridad — y restáurelos una vez en un VPS de pruebas, deliberadamente, antes de necesitarlo de verdad.

# Stop briefly for a consistent SQLite copy, or use .backup on a live db.
docker compose stop headscale
tar czf /tmp/headscale-$(date +%F).tar.gz -C /srv/headscale config data
docker compose start headscale

restic -r sftp:backup@backup.example.com:/srv/restic backup \
       /tmp/headscale-$(date +%F).tar.gz

Las actualizaciones, que son el verdadero riesgo. Esto es software anterior a la versión 1.0, y se comporta como tal: se han renombrado claves de configuración, se han movido subcomandos de la CLI, y más de una versión ha necesitado una migración documentada en lugar de un simple reinicio. Nada de eso es una razón para evitarlo — es una razón para tener una rutina. Lea las notas de la versión antes de descargarla. Haga primero la copia de seguridad de arriba. Compare su archivo de configuración con el ejemplo publicado con la nueva versión, porque ahí es donde se delatan las claves renombradas. Suba una versión menor cada vez, no tres de golpe. Y mantenga anotada la etiqueta de imagen anterior, porque poder revertir en treinta segundos es lo que hace que todo esto tenga poco riesgo.

Después, ponga un recordatorio mensual para revisar dos cosas: la lista de dispositivos registrados, para que las máquinas que dio de baja hace seis meses dejen de ser miembros, y las fechas de caducidad, para que nada se caiga en silencio en un mal momento. Una VPN de malla es uno de los pocos servicios que falla en silencio — todo sigue funcionando hasta la única vez que necesitaba el dispositivo que había caducado sin que nadie se diera cuenta.

La parte honesta · Lo que esto no hace

Ha recuperado el mapa. No se ha vuelto invisible.

Autoalojar el plano de control es una mejora real y concreta, y no es un truco de desaparición. Cinco cosas siguen siendo ciertas después de hacer todo lo anterior, y conocerlas es la diferencia entre una defensa de verdad y un cuento tranquilizador.

El servidor de control es un punto de conexión público y con nombre. Todos los dispositivos marcan hacia él, así que tiene un nombre de host, y ese nombre de host queda publicado en los registros de transparencia de certificados en el momento en que se emite el certificado. Es descubrible incluso si nunca enlaza a él, y su dirección es la única constante que comparten todos sus dispositivos. Use un subdominio de un nombre que ya publique, en lugar de uno que describa lo que es.

Headscale es una reimplementación, y lo dice abiertamente. No está construido ni respaldado por Tailscale, la paridad de funciones es parcial por construcción, y parte de lo que vende el producto alojado — la consola web, la flota pública de relés, los caminos pulidos de inicio de sesión único — o bien no existe aquí, o es un proyecto de terceros que nadie ha auditado. Consulte la documentación del proyecto para saber si una función existe antes de construir un plan sobre ella, y trate las actualizaciones como una tarea, no como un proceso de fondo.

Los relés por defecto siguen siendo de otra persona. Hasta que active el servidor DERP integrado, una conexión que no puede ser directa recurre a la flota pública de relés. El contenido sigue cifrado de extremo a extremo y nadie puede leerlo — pero el hecho de que dos de sus dispositivos están hablando, y cuánto, transita por infraestructura que no le pertenece. Esa es la parte de la cadena de confianza que a la mayoría se le escapa la primera tarde.

Un nodo de salida es una dirección estable, no una multitud. Enrutar su tráfico a través de su propio VPS derrota a la red de la cafetería y al perfil del ISP. No derrota la correlación, porque esa dirección le pertenece solo a usted y no cambia. La dirección compartida de una VPN comercial es peor en todos los sentidos salvo en el único que importa para esa amenaza en concreto.

La máquina sigue estando en un edificio. Un servidor alquilado funciona sobre hardware en un centro de datos con puertas y personal. Lo que cambia es que no existe un índice a nivel de producto de sus dispositivos, ninguna base de datos de una empresa que registre desde dónde se conecta cada uno, y ninguna política de privacidad que se pueda modificar el próximo trimestre. Lo que no cambia es que el disco es físico y no está en su casa.

Lo que en realidad ha comprado, con precisión: la lista de todas las máquinas que posee, el registro de desde dónde se conecta cada una, y la autoridad para añadir una nueva, quedan todos en manos de una máquina que alquila sin un nombre en particular. Esa es una afirmación estrecha y real a la vez. Solo vale lo que cuesta si el paso 06 está hecho — un plano de control autoalojado sin una restauración probada no es una mejora de privacidad, es un único punto de fallo con mejor imagen de marca.

Dimensionado · Qué pedir

El plano de control es gratis. Lo que se paga es el tráfico.

Nivel Mensual Recursos Qué ejecuta con holgura
Sentinel$3.902 vCPU · 4 GB · 120 GB · 1 GbpsEl servidor de control, un relé y un uso ligero como nodo de salida. El punto de partida correcto.
Un segundo Sentinel$3.90El nodo de salida, en su propia máquinaMantiene el tráfico reenviado alejado del plano de control
Ravelin$16.908 vCPU · 16 GB · 480 GB · 2.5 GbpsUn nodo de salida de uso diario para un hogar, a la velocidad máxima de línea
Bulwark$32.9016 vCPU · 32 GB · 960 GB · 5 GbpsUn nodo de salida de una empresa y un relé concurrido, juntos

Nada en esta tabla está dimensionado para la coordinación. El servidor de control mantiene una conexión inactiva por dispositivo y una base de datos que se mide en kilobytes; unos cuantos cientos de dispositivos no darán problemas ni al nivel más pequeño. Lo que consume una máquina es el tráfico reenviado — conexiones retransmitidas y, mucho más, un nodo de salida que carga con toda la conexión a internet de alguien. Dimensione en función del ancho de banda de subida y el rendimiento del cifrado, y recuerde que el ancho de banda es ilimitado en todos los niveles, así que la única pregunta es lo rápido que quiere que sea.

Notas de campo · Seis trampas

Seis formas de que esto salga mal. Dos de ellas parecen un problema de DNS.

Trampa 01 · Confusa

El sufijo del tailnet se solapa con el nombre de host del servidor

Elegir un sufijo de MagicDNS que sea padre o hijo del propio nombre de host del servidor de control rompe la resolución de nombres de una forma que parece una caída del DNS. Manténgalos como hermanos: vpn.example.com para el servidor, ts.example.com para el tailnet.

Trampa 02 · Silenciosa

Una ruta anunciada y nunca aprobada

El cliente informa tan contento de que está anunciando 192.168.1.0/24, y nada de lo que hay detrás del enrutador responde, porque el servidor nunca lo aprobó. No hay ningún error en ninguna parte. Apruébelo en el servidor, y luego revise la lista de rutas en lugar del cliente.

Trampa 03 · Lenta

Todo retransmitido, nada directo

Una red que bloquea el UDP saliente obliga a que toda conexión pase por un relé: funciona, es más lento, y pone una tercera máquina en el camino. tailscale status muestra relay en lugar de direct, y netcheck explica por qué. Corrija el cortafuegos, o acepte el salto con conocimiento de causa.

Trampa 04 · Expuesta

La política por defecto que permite todo, con un invitado en el tailnet

Un tailnet recién creado deja que cualquier dispositivo alcance a cualquier otro en cualquier puerto. Eso es correcto para una sola persona y deja de serlo en el momento en que se une el portátil de un contratista — incluidas las interfaces de administración que nadie sabía que estaban ahí. Escriba la política antes de cursar la invitación.

Trampa 05 · Fatal

La clave privada de la que nunca se hizo copia de seguridad

Reconstruya la máquina, restaure la base de datos, olvide el material de claves — y todos los dispositivos rechazarán el servidor en el que confiaban ayer. No hay ninguna recuperación ingeniosa; hay un día entero de volver a registrar teléfonos a mano. Copie el directorio de datos antes de que se una el primer dispositivo.

Trampa 06 · Evitable

Una etiqueta de imagen flotante en un servicio anterior a la versión 1.0

Las claves de configuración y los subcomandos de la CLI se han ido renombrando entre versiones menores. Con :latest, un reinicio sin relación alguna descarga una versión nueva y el plano de control de toda su flota se detiene. Fije la etiqueta, lea las notas de la versión, actualice a propósito.

Preguntas frecuentes · VPN de malla autoalojada

Preguntas, respondidas.

Once preguntas que surgen al construir esto — empezando por las dos que deciden si deberías construirlo siquiera.

¿Es Headscale un producto oficial de Tailscale?

No, y merece la pena ser precisos sobre lo que eso significa. Headscale es una reimplementación independiente y de código abierto del servidor de coordinación — la pieza de Tailscale que distribuye claves públicas, puntos de conexión y política. No está construida, vendida ni respaldada por Tailscale, no lleva ningún contrato de soporte comercial, y si algo se rompe, lo que lee es el rastreador de incidencias, no un ticket de soporte. Lo que sí hace es hablar el protocolo que ya habla el cliente oficial y de código abierto de Tailscale, que es la razón por la que el cliente funciona sin modificar contra ella. De ahí se siguen dos consecuencias prácticas. La paridad de funciones es parcial y siempre lo será, porque el proyecto persigue un objetivo móvil mantenido por un equipo mucho más grande — consulte la documentación propia del proyecto para saber si una función existe antes de diseñar algo en torno a ella. Y las actualizaciones merecen más cuidado que la actualización media de un contenedor: el esquema de configuración y varios subcomandos de la CLI se han renombrado entre versiones menores, que es la forma más habitual con diferencia en que la gente rompe una instalación que funcionaba.

¿Puede el servidor de coordinación leer mi tráfico?

No — y esta es la parte de la arquitectura que merece la pena entender en lugar de aceptar por fe. Cada dispositivo genera localmente su propio par de claves WireGuard, y la mitad privada nunca sale de él. Lo que un dispositivo sube al servidor de control es su clave pública, sus puntos de conexión actuales y algunos metadatos; lo que descarga es lo mismo, para cada uno de los demás dispositivos a los que tiene permiso para llegar. Los túneles se negocian entonces directamente entre los dispositivos, y el cifrado es WireGuard corriente entre dos claves que el servidor nunca ha tenido. Así que el servidor de control no puede descifrar nada, y eso es igual de cierto en el servidor de Tailscale. Lo que sí puede hacer es distinto y se comenta menos: posee el mapa. Nombres de dispositivos, nombres de usuarios, claves públicas, la IP pública desde la que se conecta cada dispositivo en este momento, qué dispositivo se despertó a las 3 de la madrugada, y la política que dice quién puede llegar a quién. También es lo que distribuye las claves, así que un servidor de control comprometido, o coaccionado, puede añadir un dispositivo a su red. Autoalojarse no resuelve un problema matemático; traslada uno administrativo a una máquina que usted posee.

¿Qué le pasa a mi red si el servidor de control se cae?

Mucho menos de lo que la gente espera, que es la parte tranquilizadora de este diseño. Los dispositivos guardan en caché el último mapa de red que recibieron, y los túneles WireGuard existentes son de igual a igual — no pasan por el servidor de control y no lo necesitan para seguir funcionando. Un reinicio del VPS durante una jornada laboral normal suele pasar inadvertido. Lo que se detiene es el cambio: ningún dispositivo nuevo puede registrarse, un dispositivo que se mueve a una red nueva puede tardar más en volver a encontrar a sus pares, las ediciones de la política no se propagan, y cualquier nodo cuya clave caduque mientras el servidor está caído no podrá renovarla. Así que la forma correcta de pensar en el servidor de control es como un plano de control y no como una vía de datos: una interrupción es una molestia, no una desconexión. Dicho esto, trátelo como producción. Haga copias de seguridad de él (paso 06), y si un departamento entero depende del tailnet, ponga el servidor de control en su propia máquina pequeña en lugar de compartirla con algo que se reinicia a menudo.

Headscale o WireGuard puro — ¿cuándo compensa de verdad un plano de control?

Cuente sus dispositivos, y cuente cuántos de ellos se mueven. WireGuard puro es una respuesta excelente para un conjunto pequeño y estático: tres o cuatro pares, puntos de conexión fijos, un archivo de configuración por cada uno, nada que ejecutar salvo el módulo del kernel. Es menos software, menos superficie de ataque y menos mantenimiento que cualquier cosa de esta guía, y nuestra guía de WireGuard lo cubre de principio a fin. El coste es que WireGuard, deliberadamente, no distribuye claves, así que cada dispositivo nuevo es una edición en todos los demás — un trabajo que crece con el cuadrado del tamaño de su flota — y los clientes itinerantes con Wi-Fi de hotel y datos móviles necesitan que alguien le vaya diciendo a todo el mundo adónde se han movido. Un plano de control es lo que le compra eso. En la práctica, el umbral ronda los cinco dispositivos, o el primer portátil que cambia de red a diario, o la primera vez que quiere una regla del tipo "el portátil del contratista llega al servidor de staging y a nada más". Por debajo de eso, use WireGuard y disfrute de la tranquilidad.

¿Funciona la app de Tailscale de mi teléfono con Headscale?

Sí — es el mismo cliente oficial, y apuntarlo a un servidor de control distinto es una operación admitida oficialmente, no un truco. La mecánica difiere según la plataforma, y ahí es donde la gente pierde una tarde entera. En Linux, macOS y Windows es un parámetro de línea de comandos en el cliente (--login-server) o el ajuste equivalente. En Android, la opción está expuesta en la propia app, detrás del número de versión en la pantalla de ajustes. En iOS, iPadOS y tvOS no hay ningún campo dentro de la app: se instala un pequeño perfil de configuración que fija la URL del servidor de control antes de iniciar sesión, lo cual es engorroso la primera vez y permanente después. La documentación de Headscale mantiene una página por plataforma exactamente para esto, y merece la pena abrirla en lugar de adivinar, porque el proceso en Apple, en particular, ha cambiado más de una vez. Una advertencia que no depende de la plataforma: una app que ya ha iniciado sesión en el propio servicio de Tailscale normalmente necesita cerrar sesión — y a veces reinstalarse — antes de aceptar un servidor distinto.

¿Necesito ejecutar mi propio relé DERP?

No para que la red funcione — pero es la diferencia entre mayormente privado y sistemáticamente privado, así que decídalo a propósito. Los servidores DERP son relés que se usan cuando dos dispositivos no pueden abrir una conexión directa: NAT simétrico en ambos extremos, un cortafuegos corporativo que se traga el UDP, un operador móvil haciendo algo creativo. El tráfico retransmitido sigue siendo WireGuard cifrado de extremo a extremo, así que quien opera el relé ve texto cifrado, no contenido. Lo que ve son metadatos: qué dos dispositivos están hablando, cuánto y cuándo. De fábrica, Headscale entrega a sus dispositivos el mapa DERP público de Tailscale, lo que significa que esos relés son de Tailscale — ha autoalojado el plano de control y ha dejado la ruta de datos de respaldo en manos de la empresa de la que se estaba alejando. Headscale incluye un servidor DERP integrado; activarlo le da un relé en el mismo centro de datos nórdico que el servidor de control. La contrapartida honesta es la cobertura: Tailscale ejecuta relés en varios continentes y usted ejecuta uno solo, así que un dispositivo en el otro extremo del mundo estará mejor servido por los suyos. Ejecutar ambos, con el suyo incluido en el mapa, es un término medio perfectamente razonable.

¿Puedo hacer que todo el tailnet use mi propio resolver DNS?

Sí, y es una de las mejores razones para construir todo esto. Headscale puede enviar una configuración de DNS a cada dispositivo que se une, así que tanto su portátil con el Wi-Fi de la cafetería como su teléfono con datos móviles resuelven a través de un resolver que usted ejecuta — con filtrado, con caché, y sin que la red local vea las consultas. Apunte el servidor de nombres global del tailnet a la IP de tailnet de la máquina que ejecuta su propio Unbound o AdGuard Home, y configure la anulación para que gane frente a lo que sea que le haya asignado el DHCP al dispositivo. Dos cosas hay que hacer bien. El resolver tiene que ser alcanzable dentro del tailnet, no en la internet pública — ese es todo el sentido, y también significa que por fin puede cerrar el puerto 53 al mundo. Y MagicDNS, que da a cada dispositivo un nombre corto dentro de un sufijo que usted elige, necesita que ese sufijo sea uno que controle y que no sea padre ni hijo del propio nombre de host del servidor de control; hacerlo mal es un fallo confuso que parece un error de DNS y en realidad es un error de configuración.

¿Qué tamaño de VPS hace falta?

Solo para el plano de control: pequeño, y luego todavía más pequeño. Headscale es un único binario de Go que guarda una base de datos pequeña de dispositivos, claves y política; el tráfico de coordinación es un goteo de conexiones long-poll, una por dispositivo, que casi todo el tiempo no transportan casi nada. Un Sentinel — 2 vCPU, 4 GB, 120 GB NVMe, $3.90 al mes — hará funcionar un hogar, una pequeña empresa, o unos cuantos cientos de dispositivos sin inmutarse. La cuestión del dimensionamiento solo se vuelve interesante cuando la misma máquina asume un segundo trabajo. Un relé DERP integrado reenvía tráfico real, así que necesita ancho de banda de subida antes que núcleos. Un nodo de salida reenvía todo el tráfico de un dispositivo, así que necesita ancho de banda de subida, una asignación de ancho de banda generosa y una CPU capaz de mantener el ritmo del cifrado a la velocidad de línea. Si piensa usar ambos, dimensione en función del tráfico y trate al servidor de control como el error de redondeo que es — o mejor aún, ponga el nodo de salida en una segunda máquina y mantenga el plano de control aburrido.

¿Es lo mismo un nodo de salida en mi propio VPS que usar una VPN comercial?

Técnicamente similares, y en términos de privacidad casi lo contrario, así que conviene tener las ideas claras. Un nodo de salida enruta toda la conexión a internet de un dispositivo a través de su VPS, así que los sitios web ven la dirección del VPS en lugar de la de su casa o su hotel, y la red local ve un único túnel cifrado en lugar de su navegación. Hasta ahí, coincide con una VPN comercial. La diferencia es la multitud. La dirección de una VPN comercial la comparten miles de clientes sin relación entre sí, que es precisamente lo que dificulta atribuirle a usted el tráfico; la dirección de su nodo de salida la usa usted, de forma estable, para siempre. Contra una red de cafetería fisgona o un ISP que construye un perfil, el nodo de salida es excelente. Contra un observador que correlaciona actividad entre sitios a lo largo de meses, una dirección dedicada es un identificador duradero, y una compartida no lo es. Use el nodo de salida para lo que se le da bien — redes locales no confiables, llegar a sus propios servicios, una dirección estable para cosas que esperan una — y lea la guía principal para la parte del modelo de amenaza que no cubre.

¿De qué tengo que hacer copia de seguridad exactamente?

Cuatro cosas, y solo una de ellas es evidente. La base de datos — SQLite por defecto, PostgreSQL si la ha migrado — guarda usuarios, dispositivos, claves públicas, rutas y claves de preautenticación. El material de la clave privada generado en el primer arranque es la parte que la gente olvida: piérdalo y todos los dispositivos rechazan el servidor con el que llevaban un año hablando, lo que significa volver a registrar toda la flota a mano. El archivo de configuración importa porque codifica los tres nombres del paso 02, y reconstruirlos de memoria es como la gente acaba cambiando uno sin querer. Y el archivo de políticas, si mantiene las reglas de acceso en disco, es lo que menos le conviene tener que reescribir. Los cuatro caben en dos directorios y juntos pesan menos que una fotografía. Cífrelos, envíelos a una máquina que no sea esta — idealmente en otra jurisdicción, que es para lo que sirve la guía de copias de seguridad — y restáurelos una vez en un VPS de pruebas, a propósito, para saber que el archivo que tiene es el archivo que necesita.

¿Le importa a NordBastion que ejecute un servidor de control y un nodo de salida en un VPS?

Un servidor de control es una carga de trabajo ordinaria y bien educada — un poco de HTTPS, un poco de UDP, prácticamente sin tráfico — y no hay nada en la política de uso aceptable que lo afecte. Un nodo de salida merece una frase de reflexión y no una lección de política: todo lo que un dispositivo envía a través de él sale a internet desde la dirección de su VPS, bajo su cuenta, así que lo que hagan sus dispositivos es aquello por lo que se conocerá esa dirección. Eso está bien y es exactamente para lo que sirve la función; también es la razón por la que compartir un nodo de salida con gente que no conoce es mala idea, igual que lo es un relé abierto. El ancho de banda es ilimitado en todos los niveles y el tráfico retransmitido es tráfico normal, así que un servidor DERP y un nodo de salida están incluidos, no medidos. Aparte de eso: la cuenta no necesita su nombre, la factura se salda en Monero o Bitcoin, y la máquina que guarda el mapa de todos los dispositivos que posee no está indexada por nadie.

Obtener la máquina

Un plano de control propio, en una cuenta que no lleva su nombre. Sin KYC, pagado en cripto.

Sentinel — 2 vCPU y 4 GB por $3.90 al mes, en Helsinki, Stockholm, Oslo o Reykjavík. Suficiente para Headscale, Caddy y su propio relé DERP, con margen de sobra para el nodo de salida si quiere tenerlo en la misma máquina. Sin correo en el alta, sin documento de identidad, y sin ninguna base de datos de una empresa que guarde la lista de todos los dispositivos que posee.

Última revisión · 2026-10-12 · Fuentes · Documentación de Headscale (referencia de configuración, configuración de clientes, ACL, DERP, CLI remota), documentación de Tailscale sobre el cliente y los nodos de salida, artículo del protocolo WireGuard, documentación de Caddy · Cadencia · anual

Alojamiento privado, construido en el Norte.