ZeroTier: свой контроллер (ztncui) на Ubuntu 24.04
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, если переменную не указывали.
Сразу после входа:
- Зайдите в раздел Users и смените пароль администратора, если использовали дефолтный.
- При желании заведите отдельного пользователя с ограниченными правами для коллег, которым нужен доступ только на просмотр.
- Проверьте раздел 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 ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →