Crea una red VPN con Headscale
Es muy probable que hayas escuchado o leído en el pasado sobre Tailscale, el servicio basado en wireguard con el que puedes crear una red VPN entre tus dispositivos para acceder a recursos remotos de forma segura. Pues bien, existe una implementación open-source de su servidor de control llamado Headscale la cual puedes alojar tu mismo y tener así mayor control de tu red vpn.
Requisitos
Según la documentación oficial, al momento de escribir esto solo especifica que es requerido tener Ubuntu 20.04 o superior y Debian 11 o superior. No menciona más nada.
En mi caso he dispuesto un VPS con Debian 11, 1 CPU, 1 GB RAM y 20 GB disco NVME.
La documentación no lo menciona, pero para mí es muy importante el agregar un dominio, si lo tienes
crea un subdominio tipo mired.midominio.tld
o como creas conveniente.
Si deseas utilizar un dominio, este deberá estar apuntando a la IP del VPS o servidor en donde vas a instalar Headscale.
Instalación
La Instalación es sumamente sencilla si se hace con paquetes para el sistema operativo en cuestión.
En mi caso usaré un vps con Debian, Headscale ofrece paquetes .deb
lo cual lo hace bastante conveniente.
Dichos paquetes se pueden encontrar en su repositorio GitHub
También puedes instalar usado contenedores Docker, pero he notado que los desarrolladores hacen énfasis en que esa no es la manera en la que ellos lo usan, por lo que no ofrecen soporte para este método y la mayoría de la documentación proviene de la comunidad. Notarás que es el mismo caso para el uso de Headscale con proxy.
Descargamos el paquete .deb con wget
# reemplaza VERSION con la ultima version disponible
wget https://github.com/juanfont/headscale/releases/download/VERSION/headscale_VERSION_linux_amd64.deb
Una vez descargado, instalamos el paquete:
# reemplaza VERSION con la version del paquete descargado
sudo dpkg -i headscale_VERSION_linux_amd64.deb
Eso es todo, ahora viene la parte divertida.
Configuración
Cuando realizas la instalación por el paquete del sistema operativo (.deb en este caso)
se genera un archivo de configuración en /etc/headscale/config.yaml
, vamos a abrir y editar
este archivo.
Curiosamente, la documentación oficial no habla mucho al respecto, sin embargo, el archivo config.yaml
viene cargado con bastantes comentarios que ayudan un poco, veamos los más importantes:
NOTA: Los valores que verás a continuación muy probablemente sean muy distintos a los que verás
en tu archivo config.yaml
. Los valores acá descritos son los que a mi consideración son los valores
ideales para un entorno productivo y los que usaré en mi caso.
server_url
server_url: https://mired.midominio.tld:443
Esta es la url que los clientes usaran para acceder al servidor, tanto tu PC como algún dispositivo móvil, usará esta URL para acceder al servidor de control Headscale para identificarse o compartir configuración.
Headscale y los clientes Tailscale usarán esta URL para generar los enlaces requeridos para confirmar y validar un nuevo equipo agregado a la red.
Nótese que en mi ejemplo he cambiado la URL de http
a https
y el puerto lo he colocado en el 443
esto debido a que lo ideal es que estas comunicaciones sean encriptadas para una mayor seguridad.
Si tienes un firewall, lógicamente vas a necesitar abrir el puerto indicado para permitir ese tráfico entrante.
listen_addr
listen_addr: 0.0.0.0:443
Acá se le indicará a headscale en qué puerto y el rango de IP se pondrá a escuchar por conexiones entrantes. Si tienes múltiples IP y solo quieres que escuche por una en específico, puedes colocar acá esa IP.
En este caso headscale escuchará por todas las IP o interfaces y lo hará por el puerto 443
grpc_listen_addr
grpc_listen_addr: 0.0.0.0:50443
Similar a listen_addr
, pero para comunicaciones gRPC, este recurso sería consumido por algún CLI
para controlar el servidor Headscale.
acme_email
acme_email: "tu_correo@email.com"
Si has usado lets-encrypt, ya sabrás para qué es.
tls_letsencrypt_hostname
tls_letsencrypt_hostname: "mired.midominio.tld"
Acá colocas el dominio que deseas usar para tu servidor headscale, este valor será usado para solicitar el certificado SSL a lets-encrypt para el dominio especificado.
tls_letsencrypt_cache_dir
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
La ubicación de almacenamiento del certificado lets-encrypt y alguno que otro metadata.
magic_dns
magic_dns: true
Este valor está bajo el apartado dns_config
.
Con esto habilitas MagicDNS,
el cual te permite acceder a dispositivos por medio de
un dominio en lugar de una IP.
base_domain
base_domain: mired.midominio.tld
Este valor está bajo el apartado dns_config
y es usado para generar
los hostname para MagicDNS.
Si por ejemplo agregas a la red un dispositivo llamado tableta
, podrás acceder
a él mediante tableta.mired.midominio.tld
cuando estés conectado a la red VPN.
Estas son todos los ajustes que considero hay que modificar para una instalación básica de Headscale.
Ejecución
Una vez instalado y configurado Headscale, tan solo falta activarlo e iniciarlo, esto lo hacemos con:
sudo systemctl enable headscale
sudo systemctl start headscale
Verificamos que se haya ejecutado correctamente con:
sudo systemctl status headscale
Creando un usuario
Este usuario va a ser usado al momento de confirmar el registro de un dispositivo en la red con el servidor de control Headscale.
sudo headscale users create mi_usuario
Agregando un dispositivo
Ya teniendo listo el servidor Headscale, queda agregar dispositivos a la red, para esto tan solo tienes que instalar el cliente Tailscale en el dispositivo deseado.
NOTA:
-
A partir de acá, cualquier comando que comience por
tailscale
se debe ejecutar en la máquina cliente ya quetailscale
es el cliente que se usa para conectarse a la red VPN. -
Cualquier comando iniciado con
headscale
se debe ejecutar en el servidor donde se instalóheadscale
, puesto que este es el servidor de control de la red VPN.
Hay dos maneras de registrar una máquina en Headscale, una es mediante un login normal, confirmando el dispositivo de lado del servidor y la otra es mediante una llave pre-generada.
En este caso solo explicaré el primer método, ya que es el más parecido a usar el servicio Tailscale.
Para esto tan solo tienes que ejecutar el siguiente comando del cliente Tailscale en la máquina a registrar:
tailscale up --login-server https://mired.midominio.tld
Esto va a generar un enlace en el servidor Headscale, al cargarlo en un navegador, el servidor Headscale te indicará un comando de confirmación a ejecutar:
sudo headscale --user mi_usuario nodes registrer --key [LLAVE DEL NODO]
En estos dos comandos vemos la importancia de tener el certificado SSL, ya que de lo contrario toda esta información de autenticación estaría circulando por internet de forma transparente y fácilmente visible a actores maliciosos.
Una vez agregado un dispositivo, podemos verlo en el servidor de control con:
sudo headscale node list
Deberías ver un listado como este:
ID | Hostname | Name | MachineKey | NodeKey | User | IP addresses | Ephemeral | Last seen | Expiration | Online | Expired
1 | Machine01 | Machine01 | [FFFFF] | [LLLLL] | user1 | 100.64.0.1, fd7a:115c:a1e0::1 | false | 2023-05-30 15:12:14 | 0001-01-01 00:00:00 | online | no
2 | Machine02 | Machine02 | [AAAAA] | [NNNNN] | user1 | 100.64.0.2, fd7a:115c:a1e0::2 | false | 2023-05-27 17:05:23 | 0001-01-01 00:00:00 | offline | no
Conectando a tu red local
Uno de los usos muy útiles de una red VPN con Tailscale es la de poder acceder a la red local desde el exterior para poder consumir recursos en ella de forma segura.
Con Tailscale es sumamente sencillo y en su mayoría lo haces con tan solo habilitar una función en un nodo desde el panel web.
Con Headscale no tenemos panel web, pero el proceso no es complicado, tan solo debemos seguir los pasos 1 y 2 de la documentación oficial de Tailscale.
Estos pasos son:
1) Habilitar IP Forwarding:
Ejecutando los comandos si tu S.O. Linux tiene la carpeta /etc/sysctl.d/
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
de lo contrario, lo agregas directamente en sysctl.conf
con los comandos:
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
2) Conecta un dispositivo a la red VPN como router de sub-red
Tan sencillo como agregar un dispositivo a la red con el siguiente comando:
sudo tailscale up --advertise-routes=192.168.1.0/24 --login-server=https://mired.midominio.tld
NOTA: Si el dispositivo ya fue agregado a la red VPN previamente, primero deberás desconectarlo con
sudo tailscale down
y luego ejecutar el comando:
sudo tailscale up --advertise-routes=192.168.1.0/24 --login-server=https://mired.midominio.tld
Nótese que es el mismo comando usado anteriormente para registrar un nuevo dispositivo a la red, la única diferencia es
el flag --advertise-routes=192.168.1.0/24
. Acá vas a reemplazar el valor por la IP de sub-red de tu red local.
Muchos routers usan 192.168.1.0/24
por defecto, por lo que este es un buen ejemplo.
Con estos dos pasos, ya tu dispositivo actúa como router de sub-red y anuncia dicha red a la red VPN, pero no está todo listo, ya que debemos habilitar dicha red en el servidor de control.
Habilitando la sub-red
Si en el servidor donde está instalado Headscale ejecutamos:
sudo headscale routes list
veremos algo como:
ID | Machine | Prefix | Advertised | Enabled | Primary
1 | Machine1 | 192.168.1.0/24 | true | false | ---
Acá vemos que el dispositivo que agregamos a la red con el flag --advertise-routes
está
anunciando la sub-red local en la que se encuentra, pero dicha red no está activa, por lo que los
otros dispositivos desconocen de ella y, por lo tanto, no pueden acceder a ella.
Para habilitarla ejecutamos:
headscale routes enable -r 1
Si ejecutamos nuevamente el comando para listar las rutas, veremos algo como:
ID | Machine | Prefix | Advertised | Enabled | Primary
1 | Machine1 | 192.168.1.0/24 | true | true | true
Lo cual nos confirma que se ha habilitado la sub-red y en consecuencia los otros dispositivos pueden tener conocimiento de ella.
Sin embargo, esto no quiere decir que desde ya cualquier dispositivo puede acceder a dicha sub-red.
Habilitar el uso de sub-red en clientes
Una vez agregado un dispositivo como router de sub-red para anunciar tu red local, y una vez habilitada dicha sub-red en el servidor de control de la red VPN, tan solo queda habilitar a los otros dispositivos de la red VPN para que puedan hacer uso de dicha red y acceder a ella.
Para esto debemos iniciar el cliente Tailscale con el siguiente comando:
sudo tailscale up --accept-routes=true --login-server https://mired.midominio.tld
Con esto, ta deberías poder acceder a la red local desde un dispositivo en el exterior conectado a la red VPN. Puedes confirmar esto haciendo un ping a cualquier dispositivo dentro de tu red local que responda a ping.
Conectando un cliente Android
Para conectar a la red VPN desde un dispositivo Android, debemos descargar e instalar el cliente Tailscale en
dicho dispositivo, una vez realizado esto debemos abrir la aplicación Tailscale y abrir y cerrar el menú tocando el
icono de tres puntos. Esto lo debes hacer 3 veces hasta que aparezca la opción Change server
.
Una vez aparezca esta opción, se procederá a colocar la URL del servidor de control Headscale, que en nuestro caso
es https://mired.midominio.tld
.
Puedes ver un video de este procedimiento en este PR
Luego de realizar esto, reinicia la app y al abrirla nuevamente inicia sesión de forma regular con la opción Sign in
,
esto debería abrir el navegador en donde Headscale te indicara el comando de confirmación a ejecutar en el servidor
donde está instalado Headscale.
Respaldo
Solo como un detalle aparte, si una vez creada nuestra red, queremos respaldar la configuración del servidor
de control y el estado del mismo, nada más se necesitaría hacer una copia del archivo /etc/headscale/config.yaml
y del
contenido de la carpeta /var/lib/headscale/
.
Esto es muy útil si se quiere mover el servidor de control a otra máquina sin tener que volver a reconfigurar toda la red.
Si usaste un dominio, tan solo necesitaras cambiar la IP del mismo a la IP del nuevo servidor y los clientes conectados a la red VPN ni se van a enterar de que el servidor de control se ha movido a otra máquina dado que todo quedara igual.
Cabe destacar que eso es así de simple si usas sqlite como base de datos, el cual es la base de datos por defecto de Headscale. Si al contrario, usaste PostgreSQL, entonces deberás hacer un respaldo de la misma y moverla si así lo requiere.
Conclusión
Si mal no recuerdo, este es un nuevo método de instalación oficial de Headscale, anteriormente solo se disponía de un binario y había que
realizar más ajustes y configuraciones para tener el servidor funcionando. Con los nuevos paquetes .deb
la tarea se hace mucho más sencilla.
Hay algunas otras configuraciones interesantes en Headscale muy propias de la forma en la que está creada una red Tailscale como lo es el uso de los DERP, pero eso lo comentaré en otra ocasión.
Con todo esto, es muy práctico poder crear toda una red VPN autoalojada y administrada por uno con total control de la misma para poder ya sea conectar dispositivos de forma segura o establecer comunicación desde internet con tu red local para poder consumir recursos en ella, o simplemente usar alguno de los dispositivos en tu red como nodo de salida de internet como si se tratase de una VPN comercial para salir a internet con otra IP.