Open source · BSD-3-Clause · self-hosted
Свой control-сервер Tailscale — и нормальная админка к нему.
Подключить машину, выдать доступ, пустить трафик через нужный узел —
без правки policy.hujson и SSH на ноды.
Зачем
Панель не заменяет headscale и не проксирует трафик. Она берёт на себя то, что иначе делается руками — в CLI и в файле политики.
| Задача | С NodeRoost | Без панели |
|---|---|---|
| Выдать доступ | правило «кто → куда → порт» мышью | править policy.hujson руками |
| Изоляция личных устройств | устройства не видят друг друга всегда | следить за этим самому в ACL |
| Подсеть за нодой | кнопка на карточке сервера | approve-routes по номеру ноды в CLI |
| Трафик к нужному адресу | указать домен — адрес панель обновит сама | подобрать CIDR и следить за сменой IP |
| Маршрут на самой ноде | агент применяет сам | SSH на каждую машину |
| Выход в интернет | у каждого устройства свой список шлюзов | exit-node открыт всем, кто прошёл ACL |
| Кто сейчас онлайн | история и алерты в Telegram | nodes list — только срез на сейчас |
| Подключить машину | ключ и готовая команда под нужную ОС | создать ключ в CLI и продиктовать команду |
| Где стоит сервер | флаг страны по внешнему адресу | помнить самому или лезть в whois |
| Бэкап | снимок по расписанию, с проверкой | копировать sqlite-файл вручную |
| Ошибка в правилах | откат к предыдущей рабочей версии | править файл и применять заново |
Сценарии
Машины находят друг друга сами — в облаке, в офисе, дома, за чужим NAT. Белый адрес и проброс портов для этого не нужны, а кто с кем говорит, решаете вы.
Офис и склад начинают видеть сети друг друга. На каждой стороне ставите по ноде, она объявляет свою подсеть, вы её одобряете — дальше правилами решаете, кто куда ходит. Белый адрес не нужен ни там, ни там.
Серый адрес, роутер не ваш, попросить о пробросе порта некого. Ставите ноду на этот компьютер — и он появляется в сети. Доступ открываете только своему ноутбуку и только на нужный порт. TeamViewer и обратный туннель не нужны.
База, IPMI, API кластера, морда роутера живут на адресах тайлнета. Наружу не открыт ни один порт, отдельный бастион не нужен. Доступ даёте на конкретный порт, а не на сервер целиком.
Доступ выдаётся не на сервер целиком, а на порт: дали 5432 — подрядчик видит базу и больше ничего, ни SSH, ни админку. Выдать можно сразу на роль — группу серверов: добавили в неё ещё один, он появился у подрядчика сам. Закончил работу — удалили его устройство, и доступ исчез везде сразу.
Помечаете сервер шлюзом — и трафик тех, кому вы его разрешили, выходит в интернет с его адреса. Переключается это в клиенте Tailscale самим человеком, но в списке у него только те шлюзы, которые вы ему дали.
Сервер выходит в интернет через выбранный узел: его запросы приходят наружу с адреса шлюза — например, из нужной страны. Включается и выключается галкой в карточке сервера.
Обычно после такого сервер пропадает: ответы на входящие соединения уходят в туннель и не доходят обратно — рвётся SSH, перестаёт открываться сайт. Здесь этого нет: ответ уходит тем же путём, которым пришёл запрос, и сервер остаётся доступен по своему адресу.
Партнёр пускает только с одного IP, а ходить к нему нужно с ноутбука. Указываете в панели: к этому адресу — через edge-1, чей IP у партнёра в списке. Запросы приходят к нему уже от edge-1, а весь остальной трафик ноутбука идёт напрямую.
Ни белого IP, ни DDNS, ни проброса портов на роутере. Ставите ноду на домашний сервер и заходите к нему откуда угодно — с телефона, ноутбука, рабочего компьютера — так же, как заходили бы из дома.
Машины стоят у разных провайдеров и в разных дата-центрах, общей сети между ними нет: раннер льёт в базу, бэкап уезжает в хранилище, приложение стучится в соседний ДЦ.
Раньше ради этого открывали порт наружу и держали белый список адресов на файрволе, который ломался при каждом переезде. Теперь машины видят друг друга напрямую, а доступ — одно правило в панели.
Обычный VPN заворачивает в себя всё подряд. Здесь ноутбук выходит в интернет напрямую и быстро, а через сеть идёт только то, что вы указали: подсети офиса, нужные сервисы, отдельные адреса.
Переехали в другой дата-центр, провайдер выдал новый адрес, машину увезли из офиса домой. В тайлнете у неё прежний адрес и прежнее имя, так что правила, скрипты и закладки переписывать не нужно.
Никаких .ovpn по почте. Человек получает одноразовый
ключ и одну команду под свою систему — через минуту он в сети.
Отобрать доступ — удалить устройство, а не перевыпускать конфиги
всем остальным.
Пока сервер отвечает на 22-м порту, его круглосуточно перебирают чужие боты. Подключив ноду, порт на публичном интерфейсе можно закрыть насовсем — и заходить на адрес в сети, по правилу из панели.
Снаружи стучаться становится некуда, а список тех, кому вход открыт, лежит в одном месте и правится мышью.
Провайдер зарезал порт, белый адрес под атакой, кто-то переписал правила на файрволе, лёг корпоративный VPN — а зайти надо сейчас. Ноде для связи достаточно исходящего доступа наружу, поэтому машина остаётся достижимой, когда снаружи к ней не подступиться.
Панель в самом соединении не участвует: даже если она недоступна, уже работающие подключения продолжают работать.
IPMI, камеры, принтер, управляемый свитч, старый NAS — клиента туда не установить, а дотянуться надо. Ставите ноду на любую машину в той же сети, она отдаёт подсеть, вы её одобряете — и работаете со всем этим по внутренним адресам, как будто сидите рядом.
Доступ выдаётся по-прежнему правилом: кому и на какой порт.
Модель
headscale про это ничего не знает — для него все машины просто ноды.
Деление на серверы и устройства придумали мы, живёт оно в базе панели.
Разница в одном: к серверу можно открыть доступ, к устройству — нельзя.
Поэтому серверы ходят и друг к другу, а устройства друг друга не видят вовсе.
Сервер
Устройство
Интерфейс
Четыре экрана, на которых происходит почти всё.
Как устроено
В headscale панель ходит по внутренней сети Docker — управляющий API
наружу не выставлен.
Снаружи доступно только то, что нужно клиентам Tailscale: подключиться
и получить карту сети.
Установка
Панель, Postgres и сам headscale поднимаются одним файлом. Обратный прокси выдаёт TLS и держит панель за списком доверенных адресов.
# 1. забрать репозиторий git clone https://github.com/mihsergeev/NodeRoost.git cd NodeRoost # 2. домены, секреты, список доверенных адресов cp .env.example .env && $EDITOR .env # 3. поднять docker compose up -d # 4. подключить ноду — команду выдаёт панель curl -fsSL https://control.example.com/agent/<токен>/setup | sh
databaseghcr.io/mihsergeev/noderoost-backend и -frontendБезопасность
Всё перечисленное работает сразу после установки — включать или настраивать отдельно ничего не нужно.