Tailscale es un servicio de red privada virtual (VPN) que facilita la creación de redes seguras y privadas entre dispositivos, usuarios y servicios.

Introducción

Tailscale utiliza el protocolo WireGuard para proporcionar conexiones seguras y encriptadas de extremo a extremo. Algunas características clave de Tailscale incluyen:

  • Configuración sin complicaciones: No requiere configuración manual, lo que permite desplegar una VPN de manera rápida y sencilla.
  • Acceso remoto seguro: Permite acceder de forma segura a recursos en cualquier infraestructura, ya sea en la nube, en redes privadas virtuales (VPC) o en redes locales.
  • Segmentación de red granular: Permite segmentar la red para asegurar que los usuarios correctos tengan acceso a los recursos adecuados.
  • Integraciones: Tailscale se integra con más de 100 herramientas y servicios, lo que facilita su incorporación en cualquier flujo de trabajo.

Creación del LXC

Tailscale se ejecutará sobre un LXC creado desde la Shell del servidor Proxmox contestando a las preguntas de mi script create_ct.sh:

root@pve:~# ./create_ct.sh 
Introduce el CT ID: 311
Introduce el nombre del contenedor: tailscale
Privilegiado (yes/no) [no]: 
¿Utilizarás Docker? (yes/no) [no]: 
Introduce el password del usuario 'root': 
Confirma el password del usuario 'root': 
Introduce el tamaño del disco (GB) [8]: 4
Introduce la memoria RAM (MB) [512]: 
Introduce el número de cores [1]: 
Introduce la dirección IP (192.168.1.x): 192.168.1.95
Introduce los servidores DNS (separados por espacios) [192.168.1.81 192.168.1.82]: 
¿Quieres montar /datos/samba/media en el CT? (yes/no) [no]:

Antes de poner en marcha el LXC, hay que añadir las siguientes líneas al fichero /etc/pve/lxc/311.conf para poder usar el dispositivo TUN/TAP /dev/net/tun dentro del contenedor:

lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file

A continuación, se inicia el LXC mediante el comando pct start 311 desde la Shell de Proxmox o usando el botón Start desde la configuración del propio LXC.

Acceder al LXC

Se puede acceder al LXC utilizando la opción Console de la GUI o, mucho mejor, mediante SSH gracias a la configuración de las claves públicas que se hizo en el mismo:

ssh root@192.168.1.95

Una vez dentro del LXC, hay que:

  • completar el asistente de instalación TurnKey GNU/Linux - First boot configuration
    • Pulsar el botón Skip en la pantalla Initialize Hub Services
    • Pulsar el botón Skip en la pantalla System Notifications and Critical Security Alerts
    • Pulsar el botón Install en la pantalla Security updates
    • Pulsar el botón Advanced Menu
    • Seleccionar la opción Quit para salir de la consola de configuración
    • Pulsar el botón Yes para confirmar
  • reiniciar el LXC, sobretodo si hay una actualización del kernel (shutdown -r now)
  • reconfigurar la zona horaria (dpkg-reconfigure tzdata y seleccionar Europe/Madrid)
  • actualizar los paquetes (apt update y apt upgrade -y)
  • desinstalar el paquete etckeeper (apt purge etckeeper)
  • reiniciar el LXC

Instalación de Tailscale

La instalación de Tailscale en Debian bookworm es muy sencilla siguiendo estos pasos:

# Añadir la clave oficial GPG de Tailscale
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | \
tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null

# Añadir el repositorio a las fuentes APT
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | \
tee /etc/apt/sources.list.d/tailscale.list >/dev/null

# Actualizar los repositorios e instalar Tailscale
apt update
apt install tailscale -y

# Reiniciar el LXC
shutdown -r now

Se puede borrar el historial ejecutando el siguiente comando cat /dev/null > ~/.bash_history && history -c.

Configuración de Tailscale

Si se habían añadido las líneas para montar el dispositivo TUN/TAP en el contenedor, el servicio tailscaled debería haberse iniciado correctamente y mostrar una status similar al siguiente:

root@tailscale ~# systemctl status tailscaled.service 
* tailscaled.service - Tailscale node agent
     Loaded: loaded (/lib/systemd/system/tailscaled.service; enabled; preset: enabled)
     Active: active (running) since Mon 2025-02-24 22:09:22 CET; 5min ago
       Docs: https://tailscale.com/kb/
   Main PID: 111 (tailscaled)
     Status: "Stopped; run 'tailscale up' to log in"
      Tasks: 9 (limit: 18793)
     Memory: 76.6M
        CPU: 367ms
     CGroup: /system.slice/tailscaled.service
             `-111 /usr/sbin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=41641

Habilitar forwarding de IPv4 e IPv6

Para que Tailscale funcione correctamente y permita el tráfico entre los dispositivos conectados, es necesario habilitar el reenvío (forwarding) de IPv4 e IPv6 en el sistema.

Para ello se edita el fichero /etc/sysctl.conf y se descomentan las siguientes líneas:

# Enrutar paquetes IPv4 entre interfaces de red
net.ipv4.ip_forward=1

# Enrutar paquetes IPv6 entre interfaces de red
net.ipv6.conf.all.forwarding=1

A continuación hay que recargar la configuración usando el comando sysctl -p y, finalmente, reiniciar Tailscale con el comando systemctl restart tailscaled.service.

Crear red Tailscale

Para crear nuestra red Tailscale se utiliza el comando tailscale up. Al cabo de unos segundos aparecerá un mensaje en la consola con la URL desde la cual debemos iniciar sesión:

To authenticate, visit:

        https://login.tailscale.com/a/xxxxxxxxxxxxx

Como Tailscale no mantiene usuarios hay que autenticarse mediante alguno de los proveedores indicados (Google, Microsoft, etc.).

En mi caso utilizaré GitHub para autenticarme y añadir el dispositivo tal como se muestra en las siguientes imágenes:

Login Tailscale

La máquina añadida se debería ver en la sección Machines del Panel de Administración formando parte de nuestra nueva red Tailscale o tailnet:

Machine

Acceso a la LAN y nodo de salida

Dos de las configuraciones más habituales de un node en Tailscale son:

  • habilitar el subnet para permitir el acceso a la red LAN
  • convertirlo en un exit node para permitir la salida a Internet a través de él cuando estamos fuera de la LAN

El uso de un nodo de salida es especialmente útil para utilizar servicios sensibles a la dirección IP ;-)

Esto se consigue mediante los siguientes comandos:

tailscale down
tailscale up --advertise-routes=192.168.1.0/24 --advertise-exit-node

Si aparece una advertencia sobre UDP GRO forwarding hay que realizar un cambio en la interfaz eth0.

En el Panel de Administración, el equipo debería aparecer con los iconos Subnets y Exit Node tal como muestra la siguiente imagen:

Subnets/Exit Node

Ahora podemos habilitarlos accediendo al menú lateral Edit route settings..., marcando las casillas correspondientes y pulsando el botón Save:

Enable Subnets/Exit Node

Habilitar UDP GRO forwarding

GRO es una técnica de optimización de red que reduce la sobrecarga del procesamiento de paquetes al agrupar múltiples paquetes de red más pequeños en uno más grande.

En Tailscale, si el dispositivo Linux está actuando como exit node o subnet router, se aconseja habilitar la función de reenvío de GRO (Generic Receive Offload) para paquetes UDP recibidos en la interfaz eth0 y deshabilitar la lista GRO de recepción en la misma interfaz:

ethtool -K eth0 rx-udp-gro-forwarding on rx-gro-list off

Como esta configuración se pierde al reiniciar la máquina, es necesario crear un servicio de systemd para ejecutar los comandos al inicio.

Para ello únicamente hay que crear un fichero /etc/systemd/system/ethtool.service con el siguiente contenido:

[Unit]
Description=Configurar ethtool en inicio
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool -K eth0 rx-udp-gro-forwarding on
ExecStart=/usr/sbin/ethtool -K eth0 rx-gro-list off
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

A continuación se recarga la configuración y se habilita el nuevo servicio:

systemctl daemon-reload
systemctl enable ethtool.service

Si todo funciona correctamente, al reiniciar este servidor la configuración debería ser la correcta:

root@tailscale ~# ethtool -k eth0 | grep rx-udp-gro-forwarding   
rx-udp-gro-forwarding: on

root@tailscale ~# ethtool -k eth0 | grep rx-gro-list
rx-gro-list: off

Deshabilitar Key expiry

Para evitar que las claves de este nodo expiren y nos quedemos sin acceso, seleccionar Disable key expiry en el menú lateral del dispositivo.

Troubleshooting

Para ver los mensajes de log desde que se puso en marcha el servicio tailscaled se puede usar el comando journalctl filtrando por servicio y hora de inicio:

journalctl -u tailscaled --since="$(systemctl show -p ActiveEnterTimestamp tailscaled.service | \
awk -F'=' '{print $2}')"

Tailscale en Android

La instalación de Tailscale en Android es muy sencilla. Después de haber descargado la aplicación desde la Play Store, únicamente hay que autenticarse para registrar el dispositivo en nuestra tailnet.

Cuando se activa Tailscale en Android funciona como cualquier otra VPN pero:

  • si no se activa el exit node, la salida a Internet se realizará a través de la red Wi-Fi o de datos móviles que tengamos en ese momento.
  • si se activa el exit node, la salida a Internet se realizará a través del nodo que tenemos en casa. Esto hará que la dirección del teléfono sea la dirección IP pública de casa ;-)

Se puede comprobar fácilmente nuestra dirección IP con el servicio 2ip.io.

En Android no existe “VPN on Demand como en iOS por lo que habrá que activar o desactivar la VPN de forma manual o utilizar alguna aplicación como Tasker para automatizarlo.

Se puede encontrar un ejemplo de este método en el siguiente Tutorial: Turn Taiscale on/off automatically using Tasker (Android).

Usar Pi-hole como DNS

Si se tiene Pi-hole como servidor DNS como es mi caso, se podrían añadir la dirección IP de ese servidor y entonces Tailscale lo utilizará cuando esté activada la VPN.

  • Acceder a DNS - Global nameservers
  • Añadir un nameserver de tipo Custom: <IP de Pi-hole #1>
  • (Opcional) Añadir un nameserver de tipo Custom: <IP de Pi-hole #2>
  • Activar la opción Override local DNS

Esto puede ser útil para utilizar las capacidades de bloqueo de anuncios y publicidad de Pi-hole cuando estamos fuera de casa en un dispositivo móvil.

Referencias

Historial de cambios

  • 2025-02-24: Documento inicial
  • 2025-02-27: Revisión y publicación