Перейти к основному содержанию

nebula-mesh: панель управления для Nebula, которую я собрал сам

Пару месяцев назад я перевёл инфраструктуру с Tailscale на Nebula1. Открытая лицензия, своя PKI, никакой зависимости от чужих координационных серверов — всё то, чего мне не хватало раньше. Сеть заработала и работает до сих пор.

А потом начались будни. Добавить сервер — выпусти сертификат руками, скопируй конфиг, перезапусти. Сертификат скоро протухнет — вспомни про это до того, как узел отвалится. Поменялось правило firewall — пройдись по всем хостам. Через месяц такой ручной возни я понял, что мне нужна панель управления. А готовой, которая бы меня устроила, не нашлось. Так появился nebula-mesh2.

Что такое Nebula, если коротко

Nebula — overlay-сеть, которую сделали инженеры Slack и открыли под MIT-лицензией в 2019 году. Подробно я разбирал её в прошлой статье1, тут повторю только суть.

Это виртуальная сеть поверх обычного интернета. Узлы соединяются между собой напрямую (P2P), а не гоняют трафик через один центральный VPN-сервер. Несколько узлов работают как lighthouse — «маяки», к которым обращаются остальные, чтобы найти друг друга и пробить путь сквозь NAT. Шифрование — на основе Noise, того же, что в WireGuard и Signal.

Главное для нашего разговора: у Nebula нет облака. Доверие в сети держится на сертификатах. Вы заводите собственный центр сертификации (CA), храните его у себя, и каждый узел получает сертификат, подписанный этим CA. В сертификате записаны имя хоста, его адрес в виртуальной сети, группы и срок действия. Никаких сторонних серверов в этой схеме нет — и это же её слабое место, когда узлов становится много.

Как это настраивается руками

Базовая настройка выглядит так. Сначала создаёте центр сертификации:

nebula-cert ca -name "Моя сеть"

Получаете два файла: ca.key — закрытый ключ, который нельзя терять и нельзя показывать никому, и ca.crt — публичный сертификат, который поедет на все узлы.

Дальше на каждый хост выпускаете свой сертификат с уникальным адресом:

nebula-cert sign -name "server-1" -ip "192.168.100.1/24" -groups "servers"

Потом пишете для каждого узла YAML-конфиг: где лежат ключи, по какому адресу искать lighthouse, какие правила firewall. Копируете конфиг и сертификаты на сервер. Запускаете. И так для каждого узла.

Для трёх машин это десять минут. Проблема в том, что машин обычно не три.

Где это начинает болеть

Чем больше сеть, тем заметнее, что Nebula не даёт инструментов управления — только утилиту для выпуска сертификатов и сам бинарник узла. Всё остальное на вас.

  • Сертификаты живут год. По умолчанию CA выпускается на год, хостовые сертификаты — тоже. Срок подходит — нужно выпустить новые на всех узлах и перезапустить Nebula везде. Забыли про один сервер — он молча выпадает из сети.
  • Конфиги разъезжаются. Поменяли правило — обходите хосты руками или поднимаете Ansible. Для десятка узлов Ansible — уже почти обязателен, и это отдельная история со своей сложностью.
  • Нет ни кнопки, ни картинки. Какие узлы сейчас в сети, у кого скоро истекает сертификат, кто не выходил на связь — всё это надо собирать по логам. Веб-интерфейса нет.
  • Масштаб умножает рутину. Сто новых серверов — это сто запусков nebula-cert sign и сто копирований файлов.

Создатели Nebula это прекрасно понимают. Поэтому у них есть платный продукт, который всю эту рутину закрывает.

Готовое решение: Defined Networking

Те же люди, что написали Nebula, основали компанию Defined Networking и сделали Managed Nebula3 — облачную панель управления. Регистрируете узел через веб-интерфейс или их агент, сертификат и конфиг прилетают сами, есть единый вход, мобильные приложения, автоматическая ротация. До 100 хостов бесплатно, дальше доллар за хост в месяц.

Решение хорошее. Я честно его рассматривал. Не подошло по одной причине: это чужое облако.

Панель управления живёт на серверах в США. А значит, между мной и моей сетью встаёт всё то, что сейчас встаёт между Россией и зарубежными сервисами: блокировки Роскомнадзора, санкции, ограничения на облачные услуги. Доступ к defined.net может пропасть не из-за их сбоя, а из-за того, что где-то по дороге закрыли очередной диапазон адресов. Строить на этом инфраструктуру, ради которой я и уходил от Tailscale за независимостью, смысла нет. Если уж self-host — то self-host до конца.

А что с готовым self-host

Я искал. Зрелых открытых панелей для Nebula почти нет — экосистема намного беднее, чем у того же Tailscale, где есть Headscale4.

Самое заметное, что нашлось, — Supernova5. Это control plane для Nebula: веб-панель, регистрация по токенам, выдача сертификатов. Но проект завязан на инфраструктуру AWS (DynamoDB, Lambda), давно не обновлялся и выглядит скорее как доказательство концепции, чем как то, на что можно положиться. Остальное, что попадалось, — демки и заброшенные репозитории.

Ничего, что я мог бы поставить на свой сервер и спокойно эксплуатировать, не нашлось. Поэтому решил написать сам.

Что получилось

nebula-mesh — это панель управления для Nebula, которая целиком живёт на вашем сервере. Никакого облака. Ставится на самую дешёвую виртуалку, хранит данные в SQLite, не тянет за собой внешних зависимостей.

Состоит из двух частей:

  • nebula-mgmt — сервер управления. Веб-интерфейс, API, центр сертификации, журнал действий. Запускается в одном экземпляре.
  • nebula-agent — лёгкий агент, который ставится на каждый узел сети. Сам регистрируется, сам забирает обновления конфига и сертификата, сам перезапускает Nebula, когда нужно.

Написано на Go. Веб-интерфейс — на htmx, без тяжёлого фронтенда.

Что умеет

  • Управление сертификатами от начала до конца. Выпуск, ротация, отзыв. Закрытый ключ CA лежит в базе зашифрованным (AES-256-GCM); мастер-ключ для расшифровки передаётся при старте и на диск не пишется. Сертификаты обновляются автоматически в фоне, до того как протухнут.
  • Регистрация узлов по одноразовым токенам. Создаёте токен в панели, агент на новом сервере его предъявляет и получает всё необходимое. Закрытый ключ узла при этом никогда не покидает сам узел.
  • Телефоны через QR-код. Для iOS и Android конфиг отдаётся QR-кодом — отсканировал в приложении Nebula и готово.
  • Несколько администраторов. У каждого свой изолированный CA. Можно заходить локальной учёткой или через OIDC (Keycloak, Authentik и подобные), есть двухфакторная аутентификация по TOTP с резервными кодами.
  • Правила firewall на уровне сети — задаются в панели, разъезжаются по узлам сами.
  • Журнал всех действий — кто, что и когда поменял. Плюс метрики для Prometheus и health-эндпоинты для мониторинга.

Как пользоваться

На управляющем сервере ставите nebula-mgmt (есть пакеты .deb и .rpm, бинарники под Linux, macOS, FreeBSD, Windows и Docker-образы), задаёте мастер-ключ и инициализируете:

export NEBULA_MGMT_MASTER_KEY=$(openssl rand -base64 32)
sudo -E nebula-mgmt init --config /etc/nebula-mgmt/server.yml
sudo systemctl enable --now nebula-mgmt

Дальше открываете панель на http://<сервер>:8080/ui/, заводите оператора и сеть. Чтобы подключить узел, создаёте для него токен, ставите на него nebula-agent и скармливаете токен. Агент сам зарегистрируется, заберёт сертификат с конфигом и поднимет Nebula. После этого он будет тихо опрашивать сервер на предмет обновлений и применять их без вашего участия. Точные команды и актуальную версию смотрите в README2 — проект ещё активно развивается, и я не хочу, чтобы статья устарела вместе с номером релиза.

Текущее состояние, честно

Проект совсем молодой — я запустил его в этом месяце. Звёзд на GitHub пока немного, и это нормально для репозитория, которому несколько недель. Статус — beta: основные сценарии (инициализация, регистрация, опрос, ротация, отзыв, журнал, несколько CA) покрыты тестами с детектором гонок, но API ещё может меняться до версии 1.0.

При этом сеть на нём уже работает по-настоящему — на ней крутится моя собственная инфраструктура. И, что меня радует, проект не одинокий: появились контрибьюторы, которые присылают разумные правки, в том числе закрывают вопросы по безопасности. За первые недели мы успели починить защиту от CSRF, сделать устойчивое хранилище nonce против replay-атак, ужесточить проверку прав операторов и изоляцию данных между ними. Для проекта такого возраста это хороший знак.

Лицензия — MIT. Если вам тоже нужна mesh-сеть на Nebula, которую можно держать целиком у себя, без оглядки на чужое облако и чужие блокировки, — посмотрите nebula-mesh . Баг-репорты, идеи и pull request’ы приветствуются.


  1. Nebula: mesh-сеть поверх интернета и мост в Tailscale — предыдущая статья, где Nebula разобрана подробно. ↩︎ ↩︎

  2. github.com/juev/nebula-mesh — репозиторий проекта, там же README с командами установки. ↩︎ ↩︎

  3. Defined Networking и их тарифы . ↩︎

  4. Headscale — открытый координационный сервер для Tailscale. ↩︎

  5. losfair/supernova — control plane для Nebula на инфраструктуре AWS. ↩︎