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


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

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

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

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

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

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

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

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

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

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

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

```sh
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 Nebula[^3] — облачную панель управления. Регистрируете
узел через веб-интерфейс или их агент, сертификат и конфиг прилетают сами,
есть единый вход, мобильные приложения, автоматическая ротация. До 100 хостов
бесплатно, дальше доллар за хост в месяц.

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

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

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

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

Самое заметное, что нашлось, — Supernova[^5]. Это 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-образы), задаёте
мастер-ключ и инициализируете:

```sh
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. После этого он будет тихо опрашивать
сервер на предмет обновлений и применять их без вашего участия. Точные команды
и актуальную версию смотрите в README[^2] — проект ещё активно развивается,
и я не хочу, чтобы статья устарела вместе с номером релиза.

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

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

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

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

[nm]: https://github.com/juev/nebula-mesh

[^1]: [Nebula: mesh-сеть поверх интернета и мост в Tailscale](/2026/04/03/nebula-tailscale/) — предыдущая статья, где Nebula разобрана подробно.
[^2]: [github.com/juev/nebula-mesh](https://github.com/juev/nebula-mesh) — репозиторий проекта, там же README с командами установки.
[^3]: [Defined Networking](https://www.defined.net/) и их [тарифы](https://www.defined.net/pricing/).
[^4]: [Headscale](https://github.com/juanfont/headscale) — открытый координационный сервер для Tailscale.
[^5]: [losfair/supernova](https://github.com/losfair/supernova) — control plane для Nebula на инфраструктуре AWS.

