Дружим Headscale + unRAID + Exit Node

Архитектура (текущая)

┌─────────────────┐         ┌──────────────────────────────┐
│   unRAID (Питер)│◄────────│  RPi5 (rp5-proxy)            │
│   Skynet / РФ   │ Tailnet │  Япония / Exit Node          │
│                 │◄────────┤  100.64.x.x                  │
│ Tailscale Plugin│  mesh   │                              │
└────────┬────────┘         └──────────────┬───────────────┘
         │                                 │
         │  (через exit node)              │
         ▼                                 ▼
┌──────────────────────────────────────────────────────────┐
│  Headscale Server (tsunagetai.vectorsigma.ru)            │
│  WebArena VPS, Япония                                    │
│  Caddy (TLS) + Headscale 0.28 (coordination server)      │
└──────────────────────────────────────────────────────────┘

Принцип работы: unRAID подключается к нашему Headscale-серверу. Сервер pi5-proxy в Японии объявляет маршрут 0.0.0.0/0 в качестве exit node. Трафик unRAID идёт через Tailscale туннель к малинке в Японии, а оттуда - в интернеты.


1. Настройка VPS (WebArena NTT)

Спецификация:

  • 2 vCPU, 2GB RAM, 20GB SSD
  • Ubuntu 24.04
  • Домен (tsunagetai.vectorsigma.ru) –> A-запись на IP WebArena VPS, плюс туда же ts.vectorsigma.ru для Magic NS
  • Порты 80/443 открыты

Установка Docker + Compose:

sudo apt update && sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

2. Headscale server

2.1. Структура

mkdir -p ~/headscale/{config,data}
cd ~/headscale

2.2. Конфиг Headscale (config/config.yaml)

server_url: https://tsunagetai.vectorsigma.ru
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 127.0.0.1:9090
grpc_listen_addr: 127.0.0.1:50443
grpc_allow_insecure: true

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

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

derp:
  server:
    enabled: false
  urls:
    - https://controlplane.tailscale.com/derpmap/default
  paths: []
  auto_update_enabled: true
  update_frequency: 3h

disable_check_updates: true
node_update_check_interval: 10s

database:
  type: sqlite
  sqlite:
    path: /var/lib/headscale/db.sqlite
    write_ahead_log: true

log:
  format: text
  level: info

dns:
  magic_dns: true
  base_domain: ts.vectorsigma.ru
  nameservers:
    global:
      - 1.1.1.1
      - 1.0.0.1

unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: "0770"

2.3. Caddyfile (Caddyfile)

tsunagetai.vectorsigma.ru {
    reverse_proxy headscale:8080 {
        header_up Host {host}
        header_up X-Real-IP {remote}
        header_up X-Forwarded-For {remote}
        header_up X-Forwarded-Proto {scheme}
    }
}

2.4. Docker compose (docker-compose.yml)

services:
  headscale:
    image: headscale/headscale:0.28
    restart: unless-stopped
    command: serve
    volumes:
      - ./config:/etc/headscale
      - ./data:/var/lib/headscale
    networks:
      - hsnet

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - hsnet

networks:
  hsnet:
    driver: bridge

volumes:
  caddy_data:
  caddy_config:

2.5. Запуск

cd ~/headscale
docker compose up -d

2.6. Проверка

# Теперь API должен отвечать 401 (требует авторизации)
curl -I https://tsunagetai.vectorsigma.ru/api/v1/nodes

3. Управление юзерами и ключами

3.1. Создание юзера (или организации, в понимании TS)

cd ~/headscale
docker compose exec headscale headscale users create unraid

3.2. Создание pre-auth key (для авто-регистрации)

# Создать ключ (без привязки к юзеру, если нужен только для tagged nodes)
docker compose exec headscale headscale preauthkeys create --reusable --expiration 87600h

# Или с привязкой к юзеру (для учёта)
docker compose exec headscale headscale preauthkeys create --user unraid --reusable --expiration 87600h

87600h - это 10 лет, если что

Сохранить ключ hskey-auth-xxxxxxxx-xxxx. Он будет использоваться для подключения девайсов без ручного подтверждения.

3.3. Просмотр ключей

# Все ключи
docker compose exec headscale headscale preauthkeys list

3.4. Управление ключами (expire и delete)

# взять ID ключа из списка выше, затем:
docker compose exec headscale headscale preauthkeys expire --id 123
docker compose exec headscale headscale preauthkeys delete --id 123

3.5. Просмотр нод

docker compose exec headscale headscale nodes list

3.6. Удаление ноды

docker compose exec headscale headscale nodes delete --identifier 1

4. Подключение unRAID к headscale

4.1. Требования

  • плагин Tailscale, ставить через Community Apps

4.2. Переключение на Headscale

# Остановить текущее подключение (если было)
tailscale down

# Полный сброс и переключение на собственный сервер
tailscale up --login-server=https://tsunagetai.vectorsigma.ru --authkey ключ-xxxxxxxxxxxx --reset --accept-routes

4.3. Проверка

tailscale status

Вывод типа:

100.64.x.x  unraid           unraid    linux   -

5. Подключение других девайсов-клиентов

5.1. Interactive регистрация

tailscale up --login-server=https://tsunagetai.vectorsigma.ru

Появится web страничка или вывод в консоли с командой, выполняем на хосте headscale:

# Устаревший вариант (deprecated):
docker compose exec headscale headscale nodes register --user satos --key xxxxxxxxxxxx

# Новый вариант (0.29.0+):
docker compose exec headscale headscale auth register --auth-id <id> --user satos

5.2. Автоматическая регистрация (pre-auth key)

tailscale up --login-server=https://tsunagetai.vectorsigma.ru --authkey ключ-xxxxxxxxxxxx

6. Настройка Exit Node

6.1. Объявление маршрута на Raspberry Pi 5

tailscale up --login-server=https://tsunagetai.vectorsigma.ru --advertise-exit-node --reset

6.2. Включение маршрута на сервере с Headscale

# смотрим маршруты всех нод
docker compose exec headscale headscale nodes list-routes

# Пример вывода:
# ID | Hostname   | Approved | Available       | Serving (Primary)
# 1  | pi5-proxy  |          | 0.0.0.0/0, ::/0 |

# аппрувим exit routes (IPv4 и IPv6 аппрувятся вместе)
docker compose exec headscale headscale nodes approve-routes --identifier 1 --routes 0.0.0.0/0,::/0

6.3. Проверяем

docker compose exec headscale headscale nodes list-routes

Статус должен быть вида: Approved: 0.0.0.0/0, ::/0, Serving (Primary): 0.0.0.0/0, ::/0.

6.4. Включаем exit node на unRAID

# узнать tailscale IP exit node
tailscale status | grep pi5-proxy

# подключить exit node
tailscale up --login-server=https://tsunagetai.vectorsigma.ru --exit-node=100.64.x.x --accept-routes

Либо руками в UI.

6.5. Отключение exit node

tailscale up --login-server=https://tsunagetai.vectorsigma.ru --accept-routes

Также можно ручками убрать в вебке.


7. Проверка работоспособности

7.1. На unRAID

# проверка IP (должен показать японский айпишник)
curl -s ipinfo.io

# доступ к заблоченным сайтам ресурсам
curl -I https://dl.tailscale.com

7.2. Между устройствами tailnet (ts.vectorsigma.ru)

# с девайса пингуем unRAID (TOPOL)
tailscale ping topol
ping 100.64.x.x
ping topol.ts.vectorsigma.ru

8. Subnets (доступ к локалке за unRAID)

Если нужно из Японии ходить на устройства в локалке Замшина (например): (в теории может сломать текущие маршруты wireguard, осторожно)

8.1. На unRAID

tailscale up --login-server=https://tsunagetai.vectorsigma.ru --advertise-routes=10.60.12.0/22 --accept-routes

8.2. На сервере Headscale

docker compose exec headscale headscale nodes list-routes

# аппрувим конкретный subnet route по ID ноды
docker compose exec headscale headscale nodes approve-routes --identifier <ID> --routes 10.60.12.0/22

8.3. Проверка с клиентского девайса

ping 10.60.12.1

9. Обновление Headscale

Перед обновлением обязательно бэкапить SQLite базу:

cp /var/lib/headscale/db.sqlite /var/lib/headscale/db.sqlite.backup
cp /var/lib/headscale/db.sqlite-wal /var/lib/headscale/db.sqlite-wal.backup 2>/dev/null
cp /var/lib/headscale/db.sqlite-shm /var/lib/headscale/db.sqlite-shm.backup 2>/dev/null
cd ~/headscale
docker compose pull
docker compose up -d

10. Краткая шпаргалка команд

Задача Команда
Запуск headscale docker compose up -d
Логи headscale docker compose logs -f headscale
Логи Caddy docker compose logs -f caddy
Список нод docker compose exec headscale headscale nodes list
Список маршрутов docker compose exec headscale headscale nodes list-routes
Аппрув маршрутов docker compose exec headscale headscale nodes approve-routes --identifier ID --routes 0.0.0.0/0,::/0
Создать pre-auth key docker compose exec headscale headscale preauthkeys create --reusable --expiration 87600h
Список pre-auth keys docker compose exec headscale headscale preauthkeys list
Удалить pre-auth key docker compose exec headscale headscale preauthkeys delete --id ID
Статус tailscale (unRAID) tailscale status
Переключить на headscale tailscale up --login-server=https://tsunagetai.vectorsigma.ru --reset
Включить exit node tailscale up --exit-node=100.64.x.x --accept-routes
Отключить exit node tailscale up --accept-routes

Минималка:

  • Версия Headscale: 0.28
  • Версия Tailscale клиента: ≥ 1.74.0

This site uses Just the Docs, a documentation theme for Jekyll.