MAATRIX / Блог / ZeroTier: свой контроллер (ztncui) на Ubuntu 24.04

ZeroTier: свой контроллер (ztncui) на Ubuntu 24.04

MAATRIX

ZeroTier удобен, пока сеть маленькая и бесплатного лимита my.zerotier.com хватает. Как только участников становится больше или вы не хотите держать топологию своей сети на чужом облаке — нужен собственный контроллер. Ниже — рабочая связка zerotier-one и веб-панели ztncui на своём сервере: вы создаёте сети, авторизуете участников и правите маршруты через свою панель, а не через личный кабинет ZeroTier.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Как устроен self-hosted контроллер ZeroTier

ZeroTier — это оверлейная L2/L3-сеть поверх обычного интернета: на каждом устройстве стоит клиент zerotier-one, который создаёт виртуальный интерфейс (обычно zt0 или ztXXXXXXXX) и обменивается зашифрованным трафиком с другими участниками напрямую или через реле. Отдельный узел в этой схеме — контроллер: он хранит список сетей, список авторизованных участников и правила (flow rules), и раздаёт эту конфигурацию клиентам.

Важный нюанс: контроллер — это не отдельный демон, а обычная функция самого zerotier-one. Любой узел с запущенным сервисом уже умеет быть контроллером — нужно только обращаться к его локальному JSON API на порту 9993 и создавать сети. Именно это и делает my.zerotier.com для бесплатных пользователей, и именно это вместо него делает ztncui, когда вы поднимаете контроллер сами.

Что это даёт на практике:

  • сети и список участников хранятся у вас, а не в облаке ZeroTier;
  • нет лимита в 25 бесплатных устройств на сеть — ограничение только в ресурсах вашего сервера;
  • полный контроль над правилами доступа, именами узлов и IP-пулами;
  • доступ к панели управления не зависит от доступности my.zerotier.com.

Что self-hosted контроллер НЕ меняет: пиринг между узлами по умолчанию всё равно идёт через корневые сервера (planet) инфраструктуры ZeroTier — они нужны для обнаружения пиров и NAT-traversal. Если требуется полная независимость от инфраструктуры ZeroTier вплоть до собственного planet-файла — это отдельная, более сложная задача, в этой статье её не касаемся.

Устанавливаем ZeroTier One на сервер

Контроллер — это обычный узел ZeroTier, поэтому сначала ставим клиент официальным скриптом:

curl -s https://install.zerotier.com | sudo bash
sudo systemctl enable --now zerotier-one

Проверьте, что сервис поднялся и узнайте адрес (node ID) — он понадобится дальше:

sudo zerotier-cli info

Вывод выглядит примерно так:

200 info 8badf00d1a 1.14.0 ONLINE

8badf00d1a в этом примере — 10-значный hex-адрес узла. Это ваш будущий controller address: на его основе формируются ID всех сетей, которые вы создадите на этом сервере (network ID = controller address + 6 hex-цифр).

Локальный API контроллера слушает на 127.0.0.1:9993 и защищён токеном, который лежит здесь:

sudo cat /var/lib/zerotier-one/authtoken.secret

Этот файл — по сути пароль к управлению всеми вашими сетями. Панель ztncui читает его автоматически из общего volume, вручную вписывать никуда не нужно, но знать, где он лежит, полезно для отладки и бэкапов.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Разворачиваем ztncui в Docker

ztncui — открытый веб-интерфейс для локального контроллера ZeroTier (проект key-networks/ztncui, вариант "все в одном" — key-networks/ztncui-aio, готовый docker-образ keynetworks/ztncui). Он поднимает внутри контейнера и zerotier-one, и саму панель, поэтому отдельно клиент внутри контейнера ставить не нужно — но, как показано выше, полезно один раз руками поднять zerotier-one на хосте, чтобы понимать механику до того, как всё спрячется в docker-compose.

Если Docker ещё не установлен, разверните его: в блоге есть отдельная статья про установку Docker на Ubuntu 24.04.

Создайте рабочую директорию и файл с переменными окружения:

mkdir -p /opt/ztncui/{data,ztdata}
cd /opt/ztncui
nano denv

Содержимое denv:

NODE_ENV=production
HTTPS_PORT=3443
HTTP_PORT=3000
ZTNCUI_PASSWD=ваш-надёжный-пароль
MYADDR=203.0.113.10
MYDOMAIN=ztncui.example.com
  • MYADDR — публичный IP сервера (используется при генерации self-signed TLS-сертификата и в подсказках интерфейса);
  • MYDOMAIN — доменное имя, если оно у вас есть; можно не заводить и обращаться по IP;
  • ZTNCUI_PASSWD — пароль администратора панели; если не задать, сервис сгенерирует случайный и запишет в лог контейнера.

Теперь docker-compose.yml:

services:
  ztncui:
    image: keynetworks/ztncui
    container_name: ztncui
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    devices:
      - /dev/net/tun
    env_file:
      - ./denv
    ports:
      - "9993:9993/udp"
      - "3443:3443/tcp"
      - "3180:3180/tcp"
    volumes:
      - ./data:/opt/key-networks/ztncui/etc
      - ./ztdata:/var/lib/zerotier-one

cap_add: NET_ADMIN и /dev/net/tun нужны, потому что внутри контейнера работает настоящий zerotier-one — ему требуется создавать сетевой интерфейс. Без этого контроллер не сможет присоединиться к глобальной сети ZeroTier и синхронизировать состояние.

Поднимаем:

docker compose up -d
docker compose logs -f ztncui

В логах при первом старте ищите строку с сгенерированным паролем (если не задавали ZTNCUI_PASSWD в denv) и убедитесь, что сервис ztncui и внутренний zerotier-one стартовали без ошибок.

Первый вход и смена пароля администратора

Откройте https://ваш-ip:3443 — браузер предупредит о самоподписанном сертификате (это ожидаемо, сертификат сгенерирован локально при старте контейнера). Логин по умолчанию — admin, пароль — тот, что вы задали в ZTNCUI_PASSWD, либо password, если переменную не указывали.

Сразу после входа:

  1. Зайдите в раздел Users и смените пароль администратора, если использовали дефолтный.
  2. При желании заведите отдельного пользователя с ограниченными правами для коллег, которым нужен доступ только на просмотр.
  3. Проверьте раздел Controller Status — там должен отображаться тот же node ID, что вы видели в zerotier-cli info на хосте (если запускали клиент отдельно) или новый адрес, сгенерированный внутри контейнера.

Самоподписанный сертификат для продакшена лучше не оставлять — об этом в разделе про безопасность ниже.

Создаём сеть и настраиваем параметры

В панели ztncui: Networks → Add Network. ID новой сети собирается автоматически из адреса контроллера. После создания откройте сеть и настройте:

  • Name — понятное имя, например office-ru;
  • IPv4 Auto-Assign — включите auto-assign pool и задайте диапазон, например 10.147.20.0/24 (это просто пример подсети, а не значение по умолчанию — выбирайте любую свободную приватную сеть, не пересекающуюся с локальными сетями участников);
  • Broadcast — обычно можно оставить включённым для небольших сетей;
  • Multicast limit — по умолчанию подходит для типовых VPN-сценариев, снижать имеет смысл только при большом числе участников;
  • Rules — вкладка с flow rules; для старта достаточно правила accept по умолчанию, точечные ограничения (например, запрет трафика между определёнными тегами) добавляются позже по мере необходимости.

Сравнение с публичным контроллером ZeroTier, чтобы было понятно, что меняется:

Параметрmy.zerotier.com (бесплатно)Свой контроллер (ztncui)
Лимит участников на сеть25Ограничен только ресурсами сервера
Где хранится конфигурацияВ облаке ZeroTierНа вашем сервере
Доступность панелиЗависит от zerotier.comЗависит только от вашего сервера
Резервное копированиеНедоступно вручнуюdocker cp / бэкап volume
Поддержка правил (rules)ПолнаяПолная

Подключаем и авторизуем участников

На клиентском устройстве (Ubuntu, Windows, macOS, Android, iOS) ставим обычный клиент ZeroTier и подключаемся к сети по её ID:

sudo zerotier-cli join <network-id>

Клиент по-прежнему обращается к глобальной инфраструктуре ZeroTier для обнаружения пиров, но конфигурацию самой сети получает от вашего контроллера — публичный my.zerotier.com тут не задействован вообще.

После join устройство появится в панели ztncui на вкладке сети в статусе неавторизованного участника. ZeroTier по умолчанию не выдаёт IP новым узлам — это осознанное решение безопасности, а не баг: любой, кто узнал network ID, может постучаться в сеть, но трафик не пойдёт, пока вы не нажмёте Auth напротив его записи.

Для каждого авторизованного участника в панели можно:

  • задать понятное имя вместо hex-адреса;
  • закрепить статический IP из пула вместо динамической выдачи;
  • назначить теги (tags) для использования в flow rules — например, разделить сотрудников и серверы;
  • в любой момент снять авторизацию — узел мгновенно потеряет доступ к сети.

Если нужно сравнить ZeroTier с более традиционными VPN-протоколами перед тем, как выбрать инструмент для конкретной задачи, — почитайте про WireGuard на Ubuntu 24.04 и разбор WireGuard против OpenVPN: ZeroTier ближе по духу к WireGuard (та же криптография в основе), но добавляет управляемую mesh-топологию и контроллер из коробки.

Безопасность продакшена: TLS, файрвол, бэкап

Три вещи, которые стоит сделать перед тем, как открывать панель для регулярной работы:

TLS от нормального удостоверяющего центра. Самоподписанный сертификат ztncui годится для теста, но постоянно кликать "продолжить, всё равно перейти" в браузере неудобно и снижает бдительность. Проще всего поставить перед контейнером обратный прокси с автоматическим Let's Encrypt — например Caddy, о нём есть отдельная статья: Caddy с авто-SSL на Ubuntu 24.04. Проксируете https://ztncui.example.com на 127.0.0.1:3443, порт 3443 наружу больше не публикуете.

Файрвол. Порт 9993/udp обязан быть открыт всем — это протокол ZeroTier, без него участники не достучатся до контроллера. А вот веб-панель (3443/3000) имеет смысл ограничить конкретными IP-адресами или VPN-подсетью, если вы заходите в неё не отовсюду. Настройка правил — в статье про UFW на Ubuntu 24.04. Учтите нюанс: Docker по умолчанию сам правит iptables и может пробрасывать порты в обход правил UFW — если вы жёстко ограничиваете доступ, проверяйте реальные iptables-цепочки (iptables -L -n), а не только вывод ufw status.

Бэкап. Две директории решают всё:

tar czf ztncui-backup-$(date +%F).tar.gz /opt/ztncui/data /opt/ztncui/ztdata

ztdata содержит identity.secret — это приватный ключ узла-контроллера. Если он потеряется и вы поднимете контроллер заново, у него будет другой node ID, а значит другой префикс network ID — все существующие сети с их участниками фактически "осиротеют". Это самая частая причина, по которой люди теряют доступ к своей же ZeroTier-сети: отнеситесь к identity.secret как к приватному SSH-ключу, а не как к обычному конфигу.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Чем self-hosted контроллер отличается от обычного ZeroTier с бесплатным аккаунтом?

Функционально — почти ничем: тот же протокол, тот же клиент на устройствах. Разница в том, где хранится конфигурация сети и кто управляет лимитами. У себя вы не упираетесь в лимит участников бесплатного тарифа и не зависите от доступности my.zerotier.com для администрирования.

Нужно ли всё равно доверять инфраструктуре ZeroTier?

Частично да: узлы по умолчанию используют публичные root-серверы ZeroTier для обнаружения друг друга и релея, если прямой P2P не удался. Свой контроллер убирает зависимость от их облака только в части управления сетью и списком участников, а не в части транспортной инфраструктуры.

Можно ли перенести уже существующую сеть с my.zerotier.com на свой контроллер?

Нет, напрямую нельзя — network ID жёстко привязан к адресу конкретного контроллера. Придётся создать новую сеть на своём контроллере и переподключить участников к новому network ID.

Что будет с участниками, если контейнер ztncui упадёт?

Уже установленные P2P-соединения между клиентами какое-то время продолжат работать по кэшированной конфигурации, но новые подключения, изменение прав и авторизация новых узлов будут недоступны до восстановления контроллера. Поэтому restart: unless-stopped в docker-compose и регулярный бэкап ztdata/data — не опция, а необходимость.

Подходит ли ztncui для десятков тысяч устройств?

Формально ограничений в самом ZeroTier немного, но ztncui — довольно простой инструмент без развитых средств массового администрирования (bulk-операций, RBAC, аудита). Для крупных корпоративных развёртываний стоит присмотреться к коммерческому ZeroTier Central Self-Hosted или альтернативным mesh-решениям.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →