Headscale en Proxmox LXC: tu propio servidor de control de Tailscale
Self-hosting

Headscale en Proxmox LXC: tu propio servidor de control de Tailscale

Ricardo Gil
12 de octubre de 2026
9 min de lectura

Traducido del original en inglés. Read this article in English →

#Headscale #Tailscale #Proxmox #Self-Hosting #Home Lab #Networking #VPN #LXC

Tailscale es un software excepcional: WireGuard por debajo, configuración de clientes facilísima y funciona a través de CGNAT y doble NAT sin configurar nada. El problema es que el servidor de coordinación (el que maneja el intercambio de llaves, el registro de dispositivos y las ACLs) está en la nube de Tailscale. Para la mayoría está bien. Pero si quieres control total de tu homelab, es una dependencia que no necesitas.

Headscale es una implementación open source y autoalojada del servidor de control de Tailscale. Lo corres tú, tus clientes se conectan a él, y el plano de datos de WireGuard sigue siendo peer-to-peer: Headscale nunca toca tu tráfico. Si ya usas Proxmox, agregar Headscale como contenedor LXC toma unos 30 minutos y te da una VPN en malla que controlas de punta a punta.

Este artículo cubre la instalación completa: LXC en Proxmox, instalación de Headscale, DNS + HTTPS con un certificado real, conexión de clientes y algunos problemas comunes que conviene conocer.

¿Para qué molestarse? El plan gratis de Tailscale es generoso

Buena pregunta. El plan gratis de Tailscale permite hasta 3 usuarios y 100 dispositivos. Para un homelab personal es suficiente. Pero hay varias razones para autoalojar:

Soberanía de datos. Los nombres de dispositivos, la asignación de IPs y las reglas de ACL viven en la nube de Tailscale cuando usas el servicio administrado. Con Headscale, esos metadatos se quedan en tu hardware.

Sin depender de una cuenta. Tailscale exige una cuenta SSO de Google, Microsoft, GitHub o Apple para iniciar sesión. Headscale usa llaves precompartidas y su propio modelo de usuarios, sin depender de OAuth.

Dispositivos ilimitados entre varios usuarios. Si administras dispositivos de tu familia o compartes acceso VPN con algunas personas de confianza, Headscale no tiene límites.

Es un gran ejercicio de aprendizaje. Correr un servidor de coordinación te obliga a entender el intercambio de llaves de WireGuard, los servidores relay DERP y cómo funcionan realmente las VPN en malla.

Hardware base

Necesitas una máquina con Proxmox encendida 24/7. El binario de Headscale es diminuto: funciona cómodamente en un Beelink EQ14 N150 o incluso en una Raspberry Pi 5. Un Beelink EQ12 Pro con un NVMe Samsung 990 Pro de 2 TB como disco principal sobra para esto. El contenedor LXC usa unos 50 MB de RAM en reposo: no es una carga que consuma recursos.

También conviene un UPS si todavía no tienes uno. Si Headscale se cae, todos tus clientes remotos pierden conectividad. Un CyberPower CP600LCD alcanza para un mini PC y un switch. Hablando de switches: si tu homelab ya pasó de unos pocos dispositivos, un switch administrable TP-Link TL-SG108E de 8 puertos te da soporte de VLANs sin gastar mucho.

Un requisito más: un dominio público. Headscale tiene que ser accesible para tus clientes, y el cliente de Tailscale valida el certificado TLS del servidor de coordinación. Necesitas un certificado real; Let's Encrypt funciona bien. Una opción cómoda es usar Cloudflare para el DNS con un certificado wildcard.

Crea el contenedor LXC

En Proxmox, crea un nuevo contenedor LXC. Esta guía usa Ubuntu 22.04 LTS como plantilla base.

bash
# On Proxmox host, pull the template if you don't have it
pveam update
pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.zst

Especificaciones que funcionan bien:

  • CPU: 1-2 núcleos
  • RAM: 256 MB (512 MB para ir cómodo)
  • Disco: 8 GB (la base SQLite de Headscale se mantiene pequeña)
  • Red: en bridge con tu bridge principal de LAN (vmbr0)
  • Nesting: activado (necesario para algunas operaciones de red)

Desde la interfaz de Proxmox: Create CT → elige la plantilla → asigna recursos → en Options activa "Nesting" → inicia el contenedor.

O por línea de comandos:

bash
pct create 200 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
  --hostname headscale \
  --cores 2 \
  --memory 512 \
  --swap 512 \
  --rootfs local-lvm:8 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --features nesting=1 \
  --unprivileged 1

pct start 200
pct exec 200 -- bash -c "apt-get update && apt-get upgrade -y"

Asigna una IP fija desde tu servidor DHCP (lo ideal, reservándola por MAC) o configúrala de forma estática dentro del contenedor.

Instala Headscale

Headscale viene como un solo binario. Descarga la última versión desde GitHub:

bash
# Inside the LXC container
export HS_VERSION=$(curl -s https://api.github.com/repos/juanfont/headscale/releases/latest \
  | grep tag_name | cut -d '"' -f4 | sed 's/v//')

wget -q "https://github.com/juanfont/headscale/releases/download/v${HS_VERSION}/headscale_${HS_VERSION}_linux_amd64.deb"
dpkg -i "headscale_${HS_VERSION}_linux_amd64.deb"

El paquete instala una unidad de systemd y crea /etc/headscale/config.yaml. Edita ese archivo: ahí está la mayor parte de la configuración.

bash
nano /etc/headscale/config.yaml

Campos clave que configurar:

yaml
# The public FQDN your clients will connect to
server_url: https://headscale.yourdomain.com

# Address and port Headscale listens on
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 127.0.0.1:9090

# TLS — either inline certs or let Headscale handle ACME
tls_letsencrypt_hostname: headscale.yourdomain.com
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
tls_letsencrypt_challenge_type: TLS-ALPN-01

# If using Let's Encrypt, Headscale needs to bind 443 directly
listen_addr: 0.0.0.0:443

# DERP — use Tailscale's public DERP servers or run your own
derp:
  urls:
    - https://controlplane.tailscale.com/derpmap/default
  auto_update_enabled: true

# IP range for your Tailnet
ip_prefixes:
  - fd7a:115c:a1e0::/48
  - 100.64.0.0/10

# DNS config pushed to clients
dns:
  magic_dns: true
  base_domain: home.yourdomain.com
  nameservers:
    global:
      - 1.1.1.1
      - 8.8.8.8

Sobre TLS: lo más fácil es dejar que Headscale obtenga su propio certificado de Let's Encrypt con el desafío TLS-ALPN-01. Para eso Headscale tiene que escuchar directamente en el puerto 443 y ese puerto debe ser accesible desde internet. Si estás detrás de CGNAT o prefieres no abrir puertos, usa el desafío DNS de Cloudflare con un cliente ACME aparte (acme.sh o Certbot) y apunta Headscale a los archivos del certificado:

yaml
tls_cert_path: /etc/headscale/certs/cert.pem
tls_key_path: /etc/headscale/certs/key.pem
listen_addr: 0.0.0.0:443

Inicia y habilita Headscale:

bash
systemctl enable --now headscale
journalctl -u headscale -f  # watch logs

Crea usuarios y llaves de pre-autorización

El modelo de usuarios de Headscale equivale al concepto de usuarios de Tailscale. Crea uno por persona (o por grupo lógico):

bash
headscale users create homelab
headscale users list

Para conectar un dispositivo, genera una llave de pre-autorización:

bash
# One-time use key, expires in 24 hours
headscale preauthkeys create --user homelab --expiration 24h

# Reusable key (useful for scripting device enrollment)
headscale preauthkeys create --user homelab --reusable --expiration 720h

Obtendrás una llave del tipo abc123.... Úsala en el cliente:

bash
# On any Linux/macOS/Windows machine with Tailscale installed
tailscale up \
  --login-server https://headscale.yourdomain.com \
  --authkey <YOUR_PREAUTH_KEY> \
  --hostname my-macbook

En iOS y Android, ve a Settings → Account → Sign in with another server → escribe la URL de tu Headscale y sigue el flujo con la llave de pre-autorización.

Después de conectar, verifica desde Headscale:

bash
headscale nodes list

ACLs y rutas

Aquí es donde Headscale realmente se gana su lugar. Puedes definir ACLs detalladas en HuJSON:

bash
nano /etc/headscale/acls.yaml
json
{
  "acls": [
    {
      "action": "accept",
      "src": ["homelab"],
      "dst": ["homelab:*"]
    }
  ]
}

Para exponer la subred de tu casa a los clientes de Tailscale (y no tener que instalar Tailscale en cada dispositivo):

bash
# On a Linux machine in your LAN that's already a Headscale node
tailscale up \
  --login-server https://headscale.yourdomain.com \
  --advertise-routes=192.168.0.0/24 \
  --authkey <KEY>

# Approve the route on the Headscale side
headscale routes list
headscale routes enable --route <ROUTE_ID>

Para esto, un pequeño Beelink SER5 Pro con Ubuntu funciona muy bien como router de subred dedicado. Otra opción es un router GL.iNet Beryl AX con un firmware compatible con Tailscale, que hace lo mismo sin configurar Linux.

Problemas comunes

El relay DERP importa más de lo que crees. WireGuard prefiere conexiones UDP directas, pero cuando ambos peers están detrás de NAT simétrico necesitan un servidor relay DERP. Tailscale opera una red global de servidores DERP, y Headscale puede (y debe) usarlos. Tu tráfico no pasa por ellos una vez que se establece una ruta directa, pero sin DERP configurado algunas conexiones entre peers simplemente no se forman. Es uno de los errores que más tiempo hace perder.

MagicDNS y split DNS. El MagicDNS de Headscale envía a los clientes un resolvedor que resuelve direcciones .home.yourdomain.com. Funciona bien, pero si ya tienes Pi-hole o AdGuard Home en tu red, puedes tener conflictos. Solución: configura tu servidor DNS local como nameserver en la configuración de Headscale y deja que él resuelva todo. Una Raspberry Pi 5 con Pi-hole y Headscale en contenedores separados lo resuelve de forma limpia.

A veces las actualizaciones rompen cosas. La API de Headscale todavía no es 1.0 estable. Cuando el cliente de Tailscale en tus teléfonos y laptops se actualiza solo, puede dejar de entenderse con versiones viejas de Headscale. Fija la versión de Headscale en producción y prueba las actualizaciones primero en un contenedor de repuesto. Guardar un binario de Headscale que sabes que funciona en una memoria USB SanDisk de 128 GB es un buen plan de recuperación.

Conflictos en el puerto 443. Si corres Nginx Proxy Manager o Caddy como proxy inverso en el mismo host, Headscale no puede usar también el 443. Opciones: (a) poner Headscale en una IP dedicada; (b) usar un LXC aparte con su propia IP solo para Headscale; (c) terminar TLS en el proxy inverso y pasarle HTTP a Headscale en un puerto interno, aunque Headscale necesita cabeceras especiales del proxy para que esto funcione bien.

Conéctalo a tu setup de Proxmox

Si ya tienes K3s u otros servicios corriendo en nodos de Proxmox, agregarlos a Headscale es sencillo. Instala el cliente de Tailscale en cada nodo de Proxmox (sí, Proxmox corre Tailscale sin problemas) y únelo con una llave de pre-autorización:

bash
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up \
  --login-server https://headscale.yourdomain.com \
  --authkey <KEY> \
  --hostname proxmox-node-1

Ahora tus nodos de Proxmox tienen IPs de Tailscale estables y enrutables, sin importar lo que asigne el DHCP de tu red local. Esto combina especialmente bien con Longhorn para el almacenamiento persistente de K3s, donde los nodos necesitan direcciones confiables entre sí.

El panorama general

Headscale es lo bastante estable para el uso diario en un homelab. El proyecto tiene mantenimiento activo desde 2021, una comunidad sólida en GitHub y una arquitectura simple: SQLite para el estado, una API REST para administrarlo y el protocolo de coordinación compatible con Tailscale.

Lo principal que pierdes frente a Tailscale administrado: la interfaz de administración pulida (Headscale tiene una CLI y una interfaz web hecha por la comunidad llamada Headscale-UI), el flujo de inicio de sesión de la app móvil y la gestión de servidores DERP propios de Tailscale si algún día quieres correr nodos DERP privados.

Lo que ganas: control total, cero dependencias externas para tu VPN en malla y un proyecto de redes realmente interesante. En un homelab con un Beelink EQ12 o un equipo en rack, es un proyecto de fin de semana que rinde frutos cada vez que entras por SSH a algo desde una cafetería sin pensarlo dos veces.


Aviso: este artículo contiene enlaces de afiliado. Si compras a través de ellos, puedo ganar una pequeña comisión sin costo extra para ti.

¿Quieres algo así para tu negocio?

Instalo infraestructura privada y autoalojada en Proxmox: IA, automatización y herramientas internas en hardware que es tuyo, documentado y entregado. Ver el stack de IA privada →

¿No sabes qué necesitas? Agenda una llamada gratis.

📬Newsletter semanal

Recibe lo mejor de homelab e IA

Sin spam. Un correo por semana. Te das de baja cuando quieras.

Comparte este artículo