Búsqueda de sitios web

Cómo ejecutar Headscale con UI en Docker Container


En este artículo, demostramos cómo ejecutar Headscale y Headscale UI utilizando Docker Containers. Nuestro artículo reciente fue específico para la instalación de Headscale en el sistema Ubuntu Linux usando el paquete .deb. El enlace a la publicación se comparte en el siguiente enlace.

  • Instalar y configurar Headscale en Ubuntu

Si no prefiere la instalación de Headscale basada en paquetes, este artículo está diseñado para usted. Headscale es una solución alternativa muy potente y de código abierto al servidor de coordinación Tailscale. Está diseñado para ser autohospedado en su propia infraestructura. Headscale se desarrolla de forma independiente y no tiene ninguna relación con la empresa Tailscale, excepto la versión reimplementada del servidor de coordinación de Tailscale.

Siga los pasos compartidos en esta publicación de blog para configurar un servidor Headscale dedicado que se ejecute en un contenedor Docker. El mismo procedimiento se puede reutilizar para la configuración de Podman/Podman Compose con pocas modificaciones. También hemos incluido la instalación de Headscale UI en la ventana acoplable.

1) Instalar el motor Docker

Comience su configuración asegurándose de que Docker Engine esté instalado y funcionando. Consulte la siguiente guía sobre la instalación de Docker en sistemas Linux.

  • Cómo instalar Docker CE en sistemas Linux

Una vez instalado puedes comprobar la versión.

$ docker --version
Docker version 24.0.7, build afdd53b

También verifique si el complemento de redacción está instalado.

$ docker compose version
Docker Compose version v2.21.0

2) Definir el archivo Docker Compose

Creemos un directorio que almacene las configuraciones y los datos de Headscale.

mkdir -p ~/headscale && cd ~/headscale

Cree una base de datos SQlite vacía en el directorio headscale:

mkdir ./config
touch ./config/db.sqlite

Cree un nuevo archivo llamado docker-compose.yml

vim docker-compose.yml

Pegue y modifique los contenidos siguientes. Si no necesita que Headscale se ejecute en el contenedor Docker, elimine sus secciones.

version: '3.9'
services:
  headscale:
    container_name: headscale
    image: headscale/headscale:latest
    command: headscale serve
    restart: unless-stopped
    ports:
        - 8080:8080
        - 9090:9090
    volumes:
        - ./config:/etc/headscale/
        - ./data:/var/lib/headscale/

  headscale-ui:
    container_name: headscale-ui
    image: ghcr.io/gurucomputing/headscale-ui:latest
    pull_policy: always
    restart: unless-stopped
    ports:
        - 9080:80

En nuestro archivo de redacción estamos:

  • Montaje config/ en /etc/headscale
  • Montaje de data/ en /var/lib/headscale/
  • Reenviar el puerto 8080 fuera del contenedor headscale para que la instancia headscale esté disponible
  • Reenviar el puerto 9080 desde el contenedor headscale-ui para que la instancia headscale-ui esté disponible

Si utiliza https en la interfaz de usuario, puede asignar puertos separados como se muestra a continuación.

- 9443:443

3) Iniciar contenedores Headscale

Descargue el archivo de plantilla de configuración.

mkdir {config,data}
wget https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml -O config/config.yaml

Modifique el archivo de configuración según sus preferencias antes de iniciar el contenedor Docker. A continuación se muestran algunas configuraciones que probablemente desee:

# Change to your hostname or host IP
# server_url: //vpn.computingforgeeks.com:8080
server_url: http://192.168.20.11:8080
# Listen to 0.0.0.0 so it's accessible outside the container
metrics_listen_addr: 0.0.0.0:9090

Inicie los contenedores usando el comando docker compose. La opción -d significa desconectar para que se ejecuten en segundo plano.

$ docker compose up -d
[+] Running 19/19
 ✔ headscale-ui 13 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                 3.2s
   ✔ 8921db27df28 Pull complete                                                                                                                                                                  0.5s
   ✔ 5e0dab5e7f18 Pull complete                                                                                                                                                                  0.5s
   ✔ e7466e9238c6 Pull complete                                                                                                                                                                  0.5s
   ✔ 9aca5eef2d98 Pull complete                                                                                                                                                                  0.7s
   ✔ 4f4fb700ef54 Pull complete                                                                                                                                                                  0.8s
   ✔ 5007d4d43f68 Pull complete                                                                                                                                                                  0.8s
   ✔ 2ebc6f305da4 Pull complete                                                                                                                                                                  1.0s
   ✔ 712d06ffc498 Pull complete                                                                                                                                                                  1.1s
   ✔ ac473b17e437 Pull complete                                                                                                                                                                  1.7s
   ✔ 36f5767e6555 Pull complete                                                                                                                                                                  1.7s
   ✔ 7c6ac0210a21 Pull complete                                                                                                                                                                  1.8s
   ✔ 7765e166cec5 Pull complete                                                                                                                                                                  1.8s
   ✔ 896f16a8f15c Pull complete                                                                                                                                                                  2.0s
 ✔ headscale 4 layers [⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                              4.4s
   ✔ 9e3ea8720c6d Pull complete                                                                                                                                                                  2.3s
   ✔ 71273269cd97 Pull complete                                                                                                                                                                  2.4s
   ✔ 007b622b7a95 Pull complete                                                                                                                                                                  2.5s
   ✔ 50a37fbfee41 Pull complete                                                                                                                                                                  2.5s
[+] Running 3/3
 ✔ Network headscale_default  Created                                                                                                                                                            0.1s
 ✔ Container headscale-ui     Started                                                                                                                                                            0.6s
 ✔ Container headscale        Started

Verifique el estado de los contenedores creados.

$ docker compose ps
NAME                IMAGE                                       COMMAND                  SERVICE             CREATED             STATUS              PORTS
headscale           headscale/headscale:latest                  "headscale serve"        headscale           45 seconds ago      Up 43 seconds       0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:9090->9090/tcp, :::9090->9090/tcp
headscale-ui        ghcr.io/gurucomputing/headscale-ui:latest   "/bin/sh -c '/bin/sh…"   headscale-ui        45 seconds ago      Up 43 seconds       443/tcp, 0.0.0.0:9080->80/tcp, :::9080->80/tcp

Puede seguir los registros del contenedor para ver qué sucede dentro ejecutando.

$ docker logs --follow headscale
2023-10-05T23:29:19Z INF go/src/headscale/hscontrol/protocol_common.go:574 > Successfully sent auth url AuthURL=http://192.168.20.11:8080/register/nodekey:af52937e8bc375a0d73a01cd453fd2f814144796b0270cedb0d126a39518c306 machine=jammy noise=true

$ docker logs --follow headscale-ui
no Caddyfile detected, copying across default config
Starting Caddy
{"level":"info","ts":1696545638.4848695,"msg":"using provided configuration","config_file":"/data/Caddyfile","config_adapter":"caddyfile"}
{"level":"info","ts":1696545638.4858341,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1696545638.4859416,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000544fc0"}
{"level":"info","ts":1696545638.486509,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"warn","ts":1696545638.4865189,"logger":"http","msg":"automatic HTTP->HTTPS redirects are disabled","server_name":"srv0"}
{"level":"warn","ts":1696545638.4865253,"logger":"http","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv1","http_port":80}
{"level":"info","ts":1696545638.4865966,"logger":"pki.ca.local","msg":"root certificate trust store installation disabled; unconfigured clients may show warnings","path":"storage:pki/authorities/local/root.crt"}
{"level":"warn","ts":1696545638.4866195,"logger":"tls","msg":"YOUR SERVER MAY BE VULNERABLE TO ABUSE: on-demand TLS is enabled, but no protections are in place","docs":"https://caddyserver.com/docs/automatic-https#on-demand-tls"}
{"level":"info","ts":1696545638.48668,"logger":"http.log","msg":"server running","name":"srv1","protocols":["h1","h2","h3"]}
{"level":"info","ts":1696545638.486689,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/home/appuser/.local/share/caddy"}
{"level":"info","ts":1696545638.4867213,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1696545638.4867342,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1696545638.4867566,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size for details."}
{"level":"info","ts":1696545638.4868112,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1696545638.486932,"msg":"autosaved config (load with --resume flag)","file":"/home/appuser/.config/caddy/autosave.json"}
{"level":"info","ts":1696545638.4869497,"msg":"serving initial configuration"}

El comando ss se puede utilizar para verificar que los puertos del host estén vinculados.

$ ss -tunlp|egrep '8080|9080'
tcp   LISTEN 0      4096         0.0.0.0:9080       0.0.0.0:*    users:(("docker-proxy",pid=364448,fd=4))
tcp   LISTEN 0      4096         0.0.0.0:8080       0.0.0.0:*    users:(("docker-proxy",pid=364428,fd=4))
tcp   LISTEN 0      4096            [::]:9080          [::]:*    users:(("docker-proxy",pid=364455,fd=4))
tcp   LISTEN 0      4096            [::]:8080          [::]:*    users:(("docker-proxy",pid=364434,fd=4))

4) Acceder al shell del contenedor

Puede acceder al shell del contenedor headscale ejecutando:

docker exec -ti headscale bash

Para ejecutar headscale-ui:

docker exec -ti headscale-ui sh

Podemos probar la funcionalidad creando un usuario en la instancia de Headscale.

 root@4f2fbe02c029:/# headscale users create computingforgeeks

Se ejecutará un comando de una línea sin ingresar al shell del contenedor.

docker exec headscale \
  headscale users create myuser

5) Unir dispositivos cliente a la red Headscale

Necesita un usuario creado en su servidor Headscale. Crearemos uno llamado computingforgeeks.

$ docker exec headscale headscale users create computingforgeeks
User created

Instalación de clientes de Tailscale en sus dispositivos

  • Cliente de Windows
  • iOS
  • Androide
  • linux
  • Mac OS

Instalación de Tailscale en Linux/BSD

Para sistemas basados en Linux y BSD, ejecute los comandos:

curl -fsSL https://tailscale.com/install.sh | sudo sh

Se puede verificar la versión de Tailscale con los siguientes comandos.

$ tailscale --version
1.50.1
  tailscale commit: f45c02bfcf5ee5790c3af278c9e974c9b9b0e771
  other commit: 36a20760a45bd1936686879b34c35146cc0c4ec1
  go version: go1.21.1

Instalación en MacOS

Puedes instalar usando Homebrew:

brew install tailscale

O ejecutando el script.

curl -fsSL https://tailscale.com/install.sh | sudo sh

Registrar una máquina (inicio de sesión normal)

En una máquina cliente, ejecute el comando de inicio de sesión tailscale:

tailscale up --login-server YOUR_HEADSCALE_URL

Vea el ejemplo a continuación.

# tailscale up --login-server http://192.168.20.11:8080

To authenticate, visit:
  http://192.168.20.11:8080/register/nodekey:410155d1792d0f81a5f39415a1a418f882208751570c2e5195f7a6842ca44e6a

Al abrir los enlaces se obtienen comandos que se ejecutarán en el servidor Headscale para registrar el dispositivo.

Listado de todos los usuarios creados en el servidor Headscale:

$ docker exec headscale headscale user list
ID | Name              | Created
1  | computingforgeeks | 2023-10-05 22:50:40
2  | myuser            | 2023-10-05 22:52:18
3  | user2             | 2023-10-05 22:59:03

Recuerde reemplazar USERNAME con su nombre de usuario válido cuando ejecute los comandos.

$ docker exec headscale \
  headscale nodes register --user computingforgeeks --key nodekey:410155d1792d0f81a5f39415a1a418f882208751570c2e5195f7a6842ca44e6a
Machine rocky8 registered

La sintaxis general al registrar una máquina usando headscale es:

docker exec headscale \
  headscale --user <username> nodes register --key <YOU_+MACHINE_KEY>

Listado de todas las máquinas agregadas a la red de malla de Headscale.

# docker exec headscale headscale node list
ID | Hostname | Name  | MachineKey | NodeKey | User              | IP addresses                  | Ephemeral | Last seen           | Expiration          | Online | Expired
1  | jammy    | jammy | [cN/Um]    | [r1KTf] | computingforgeeks | 100.64.0.1, fd7a:115c:a1e0::1 | false     | 2023-10-05 23:39:04 | 0001-01-01 00:00:00 | online | no

Registre la máquina usando una clave previamente autenticada

También puede registrar una nueva máquina utilizando una clave previamente autenticada.

Primero genere una clave usando la línea de comando:

docker exec headscale \
  headscale --user <username> preauthkeys create --reusable --expiration 24h

La ejecución del comando devuelve una clave previamente autenticada que se utiliza para conectar un nodo a headscale al ejecutar el comando tailscale :

tailscale up --login-server <YOUR_HEADSCALE_URL> --authkey <YOUR_AUTH_KEY>

Veamos el ejemplo a continuación.

# On Headscale server
# docker exec headscale headscale --user jkmutai preauthkeys create --reusable --expiration 24h
4763c4f4293b260eff230065378e5668c13db44f4569ed7b

# On Machine to be registered
# tailscale up --login-server http://vpn.hirebestengineers.com --authkey 4763c4f4293b260eff230065378e5668c13db44f4569ed7b

El comando de registro de la máquina con clave previamente autenticada no genera ningún resultado. Pero puede confirmar si se agregan nuevos nodos desde la CLI del servidor Headscale.

# docker exec headscale headscale node list
ID | Hostname | Name   | MachineKey | NodeKey | User    | IP addresses                  | Ephemeral | Last seen           | Expiration          | Online | Expired
1  | rocky8   | rocky8 | [s+TG9]    | [QQFV0] | jkmutai | 100.64.0.1, fd7a:115c:a1e0::1 | false     | 2023-10-05 17:05:58 | 0001-01-01 00:00:00 | online | no
2  | mail     | mail   | [V8WI2]    | [OvPLb] | jkmutai | 100.64.0.2, fd7a:115c:a1e0::2 | false     | 2023-10-05 17:06:32 | 0001-01-01 00:00:00 | online | no

6) Comandos útiles de Headscale

Elimina un nodo en tu red.

docker exec headscale \
  headscale node delete -i <ID>

Mover nodo a otro usuario

docker exec headscale \
  headscale node move  -i  <ID> -u <New-User>

Cambiar el nombre de una máquina en su red

docker exec headscale \
  headscale node rename  -i  <ID>  <NEW_NAME>

Caducar (cerrar sesión) una máquina en su red

docker exec headscale \
  headscale node expire -i <ID> 

Cree una clave API:

docker exec headscale \
  headscale apikeys create --expiration 90d

Lista de claves API:

docker exec headscale \
  headscale apikeys list

Caducar una clave API:

docker exec headscale \
  headscale apikeys expire --prefix "<PREFIX>"

7) Acceda a la interfaz de usuario de Headscale

Genere una clave API en el servidor Headscale.

docker exec headscale \
  headscale apikeys create --expiration 120d

Esto da un resultado similar a este.

8bnNOGwOkw.bjQXvEB4Vk9Ia1R9HupEB0yB9PFthth_Or8QcHncKmw

Abra la interfaz de usuario de Headscale en http://ServerIP_or_hostname:9080/web/settings.html

Ingrese la URL del servidor Headscale y el token generado en los cuadros. Ejemplos:

  • URL de escala principal: //api.computingforgeeks.com
  • Clave API de Headscale: 8bnNOGwOkw.bjQXvEB4Vk9Ia1R9HupEB0yB9PFthth_Or8QcHncKmw

Próximo artículo para revisar:

  • Unir pfSense a Tailscale/Headscale VPN Mesh
  • Cómo habilitar e iniciar el servidor SSH en OPNsense
  • Cómo instalar y configurar el cliente Tailscale en OPNsense

Conclusión

Headscale es una solución perfecta para pequeñas y medianas empresas que buscan crear una red de malla Tailscale y conectar dispositivos a ella. Es una solución alternativa poderosa, segura y confiable a la configuración del servidor VPN. Le brinda control total sobre la red en malla y el servidor de coordinación. Las VPN en malla utilizan un modelo de igual a igual (P2P) para crear un entorno compartido seguro para sus usuarios.

Artículos relacionados: