Инструменты пользователя

Инструменты сайта


selfhosted:zerotier

ZeroTier — оверлей-сеть

Self-hosted ZeroTier-сеть, через которую обеспечивается удалённый доступ ко всем домашним сервисам, без необходимости публиковать SSH/админ-порты в интернет. Контроллер свой, не ZeroTier Central.

TL;DR — самое важное

  • Сеть: c53bc939c1ce37d2 (имя melnoff-main-network), подсеть 172.25.30.0/24.
  • Контроллер: zt.melnoff.com (ztnet UI), это не my.zerotier.com. Авторизация участников делается там.
  • Свой moon: c53bc939c1 @ 94.103.86.3:9993 (это и есть контроллер). Файл moon: 000000c53bc939c1.moon.
  • На каждом новом клиенте — три команды, см. bootstrap_нового_клиента.
  • Если ZT «полу-работает» (онлайн, но трафик не ходит) — первым делом проверить allowManaged. См. типичные_проблемы.

Архитектура

Уровни

  1. Planets — публичные корни ZeroTier Inc. Используются для bootstrap. У вас в peers это адреса с ролью PLANET (cafe04eba9, cafe80ed74 и т.п.).
  2. Moon (свой) — ваш корень, добавленный к planets. Дублирует функцию rendezvous и даёт быстрый relay внутри РФ.
  3. Leaves — обычные клиенты сети. У них роль LEAF.

Роли узлов в сети

Узел / Description ZT addr ZT IP Public/LAN endpoint Заметки
Контроллер + moon (хост zt.melnoff.com) c53bc939c1 172.25.30.225 94.103.86.3:9993 Linux Oracle 10. ZT крутится в Docker (zyclonite/zerotier:1.16.0). Web UI = ztnet.
Этот мак 54dcf8821c 172.25.30.11 212.74.229.169:9993 macOS, ZT 1.16.1, feth2340 интерфейс.
Узел «imelnikov» (см. контроллер) 172.25.30.10 Доступ ssh imelnikov@172.25.30.10.
PVE-роутер в LAN (gateway-узел) 172.25.30.1 Бриджит ZT в 192.168.0.0/24 и 172.16.10.0/24.
Удалённый peer (sym-NAT) cab282198d 172.25.30.6 193.35.100.225 За симметричным NAT'ом — для доступа из мака требуется relay через moon.
Прочие участники 31040019d0, 35d963a742, 73db6c289d, 77b9f07f34, 7e27e08dd1, c63ddbdfe3 разное Разные клиенты сети; точное соответствие ZT-addr↔IP смотреть на zt.melnoff.com → Members.

Маршруты

Контроллер раздаёт клиентам сети (в дополнение к 172.25.30.0/24):

Target Via Что значит
172.25.30.0/24 (direct) Сама ZT-подсеть
192.168.0.0/24 172.25.30.1 Через ZT-gateway пробрасывается в физический LAN
172.16.10.0/24 172.25.30.1 Доступ к Docker-фабрике на PVE (LXC 107 = 172.16.10.1)

Push DNS

  • Зона: homepc.zt
  • Резолвер: 192.168.0.11

Push DNS применяется только на клиентах с allowDNS=1.

Контроллер на zt.melnoff.com

Стек

OpenSSH доступен как ssh root@zt.melnoff.com. На хосте Docker-стек:

Контейнер Образ Порт Назначение
zerotier zyclonite/zerotier:1.16.0 UDP 9993 (host network) Сам ZT-демон в режиме контроллера. ZT-addr c53bc939c1.
ztnet sinamics/ztnet:latest 3000 (HTTP) Современный web UI/API для управления контроллером.
postgres postgres:16-alpine (internal) БД для ztnet.

Обновлён до 1.16.0 на 2026-04-27 (in-place recreate с named volume ztnet_zerotier; identity и БД members сохранены). Compose-файл: /opt/ztnet/docker-compose.yml. Бэкап volume оставлен в /root/zt-volume-backup-*.tgz.

Полезные команды на контроллере

# войти на хост
ssh root@zt.melnoff.com
 
# на хосте — zerotier-cli работает только через docker exec
docker exec zerotier zerotier-cli info
docker exec zerotier zerotier-cli listnetworks
docker exec zerotier zerotier-cli peers
 
# проверить достижимость члена сети с самого контроллера (тест L3)
docker exec zerotier ping -c 3 172.25.30.6
 
# логи
docker logs --tail 100 zerotier
docker logs --tail 100 ztnet
 
# REST API контроллера (через токен из контейнера)
TOK=$(docker exec zerotier cat /var/lib/zerotier-one/authtoken.secret)
docker exec zerotier curl -s -H "X-ZT1-Auth: $TOK" \
  http://localhost:9993/controller/network/c53bc939c1ce37d2/member

Web UI (ztnet)

  • Адрес — на порту 3000 хоста (либо за nginx). Логин/пароль — у владельца.
  • Авторизация новых member'ов — там.
  • Здесь же редактируются: name, ipAssignments, capabilities/tags, routes, dns push, broadcast, multicast limits.

Bootstrap нового клиента

Минимальный набор шагов на любом новом узле, который должен подключиться к сети:

Linux

# 1. Установка (Debian/Ubuntu)
curl -s https://install.zerotier.com | sudo bash
 
# 2. Присоединение к сети
sudo zerotier-cli join c53bc939c1ce37d2
 
# 3. Подключить свой moon (важно для symmetric-NAT окружений)
sudo zerotier-cli orbit c53bc939c1 c53bc939c1
 
# 4. Разрешить демону применять выданные IP/маршруты
sudo zerotier-cli set c53bc939c1ce37d2 allowManaged=1
 
# 5. Авторизовать узел в zt.melnoff.com → Members → ✓ Auth

macOS

# 1. Установка через Homebrew или из dmg на zerotier.com
brew install --cask zerotier-one
 
# 2-5: те же команды что на Linux. Бинарник в /usr/local/bin/zerotier-cli
sudo zerotier-cli join c53bc939c1ce37d2
sudo zerotier-cli orbit c53bc939c1 c53bc939c1
sudo zerotier-cli set c53bc939c1ce37d2 allowManaged=1

Windows

  1. Поставить ZeroTier One MSI с zerotier.com.
  2. В трее → Join Network → ввести c53bc939c1ce37d2.
  3. В админ-cmd: zerotier-cli orbit c53bc939c1 c53bc939c1.
  4. Авторизовать узел в Members на zt.melnoff.com.

Через .moon файл (альтернатива orbit)

Положить файл 000000c53bc939c1.moon в:

  • Linux: /var/lib/zerotier-one/moons.d/
  • macOS: /Library/Application Support/ZeroTier/One/moons.d/
  • Windows: %PROGRAMDATA%\ZeroTier\One\moons.d\

После рестарта демона moon будет загружен. zerotier-cli listmoons должен показать его. Это полезно если узел стартует в условиях, когда planet'ы недоступны.

Зачем нужен свой moon

Moon — это ваш собственный root-сервер сети ZeroTier (планета ZT-Inc + ваша «луна» = два корня).

Решает три задачи

  1. Скорость rendezvous и relay. Публичные planet'ы географически далеко (Амстердам, Сингапур, США — latency 150-240 мс). Свой moon в РФ — 8-11 мс. При невозможности hole-punch'а (см. ниже) трафик идёт через корень — на planet'е это медленно.
  2. Symmetric-NAT окружения. Если узел за «строгим» NAT'ом (типа корпоративного или мобильного), p2p-соединения не пробиваются. Без relay через близкий moon связь не работает совсем. Конкретный пример в этой сети — узел 172.25.30.6 (cab282198d) за симметричным NAT'ом 193.35.100.225.
  3. Независимость от публичной инфраструктуры ZT-Inc. Если planet'ы временно недоступны (блокировка провайдером, DDoS, downtime), свой moon продолжает работать.

Когда moon **не нужен**

  • На самом узле-moon (он сам и есть root).
  • Если оба пира за обычным cone NAT-ом — hole-punch через planet'ы работает напрямую, moon не используется.

Технически

Moon — это подписанный JSON-документ:

{
  "id": "c53bc939c1",
  "roots": [{
    "identity": "c53bc939c1:0:b9b6...<публичный ключ>",
    "stableEndpoints": ["94.103.86.3/9993"]
  }],
  "signature": "...",
  "timestamp": ...,
  "updatesMustBeSignedBy": "..."
}

Создание новой moon: на узле-кандидате zerotier-idtool initmoon /var/lib/zerotier-one/identity.public > moon.json, отредактировать stableEndpoints, потом zerotier-idtool genmoon moon.json → получится .moon. Распространять на клиентов через moons.d/ или команду orbit.

Типичные проблемы

1. ''allowManaged=0'' — IP «висит», но реально не на интерфейсе

Симптом. zerotier-cli info = ONLINE, listnetworks = OK с правильным IP, peers показывает DIRECT пира — но любой ICMP/TCP до него падает с No route to host или просто таймаутится. Под капотом: ifconfig <ZT iface> не показывает inet-адрес, в netstat -rn нет маршрута на 172.25.30.0/24. Трафик уходит через default route (например, на параллельный VPN).

Причина. Локальная политика клиента запрещает ZT-демону применять IP/маршруты, выданные контроллером.

Лечение.

sudo zerotier-cli set c53bc939c1ce37d2 allowManaged=1

⚠️ leave сети сбрасывает этот флаг в 0. После любого leave/join цикла — выставить заново.

2. Moon не подхватывается из ''moons.d/''

Симптом. Файл .moon в каталоге есть, но zerotier-cli listmoons возвращает [].

Причина. Демон читает moons.d/ только при старте.

Лечение. Без рестарта: sudo zerotier-cli orbit <moonId> <moonId> (для нашей сети — sudo zerotier-cli orbit c53bc939c1 c53bc939c1). С рестартом: sudo launchctl kickstart -k system/com.zerotier.one (macOS) или sudo systemctl restart zerotier-one (Linux).

3. Узел в Central «онлайн», но ''paths: 0'' и недоступен

Симптом. На контроллере (docker exec zerotier zerotier-cli peers) узел виден как DIRECT с low latency. На клиенте этот же узел в peers имеет paths: 0, latency: -1. Пинг не доходит, ARP не resolve'ится.

Причина. Кэш member-info на клиенте залип — endpoint от moon не получен.

Лечение.

sudo zerotier-cli leave c53bc939c1ce37d2
sudo zerotier-cli join c53bc939c1ce37d2
sleep 5
sudo zerotier-cli set c53bc939c1ce37d2 allowManaged=1   # ← обязательно после join

В ZT 1.16 relay-only пути не показываются в массиве paths — поэтому paths: 0 не означает «недоступен», просто «нет p2p». Всегда пробуйте ping реально.

4. ''ACCESS_DENIED'' в ''listnetworks''

Причина. Узел не авторизован контроллером.

Лечение. На zt.melnoff.com → Members → найти узел по ZT-addr (10 hex) → поставить галку Auth.

5. Дублирование ICMP-ответов (''DUP!'')

Симптом. При ping появляются строчки с пометкой (DUP!).

Причина. На маке параллельно работает второй TUN-VPN (например, AdGuard на utun4 с 198.18.0.1) — он подхватывает копии пакетов.

Лечение. Не критично, на функциональность не влияет. Если раздражает — проверить, не тащит ли VPN-клиент broadcast/multicast в свой туннель.

Диагностический playbook

Делать в этом порядке. Каждый шаг предполагает, что предыдущий вернул «зелёный» результат.

  1. Демон ONLINE? sudo zerotier-cli infoONLINE. Если OFFLINE — UDP 9993 наружу заблокирован, либо демон не запущен.
  2. Сеть OK? sudo zerotier-cli listnetworksOK и осмысленный IP. Если ACCESS_DENIED — авторизовать в Central. Если REQUESTING_CONFIGURATION дольше 30 сек — контроллер недоступен.
  3. allowManaged=1? sudo zerotier-cli get <nwid> allowManaged. Если 0 — фиксить (см. проблема №1).
  4. Путь до пира. sudo zerotier-cli -j peers → достать запись по ZT-addr целевого узла. Смотреть массив paths. Если пусто — это не обязательно «недоступен» (см. проблема №3), просто нет p2p.
  5. Moon загружен? sudo zerotier-cli listmoons → должна быть запись с id = 000000c53bc939c1. Если пусто — orbit (см. проблема №2).
  6. Stale member cache? leave/join цикл (см. проблема №3).
  7. Последняя надежда: рестарт демона; апгрейд контроллера до ZT 1.16.x.

Полезные ссылки

Резервная копия moon-файла

На случай, если контроллер zt.melnoff.com будет недоступен (катастрофа / блокировка / порт 9993 закрыт), а нужно поднять новый клиент — вот канонический moon-файл в base64.

В файле нет приватных ключей — только публичная identity moon-узла, его stable endpoint и подпись world'а. Поэтому хранить его в публичной wiki безопасно.

  • Имя файла: 000000c53bc939c1.moon
  • Размер: 259 байт
  • SHA-256: 76e8a39807413a5b650c61d133d53285492484af0a7d519cf72a86dd3ce76cf6
  • Извлечён с: zt.melnoff.com:/var/lib/zerotier-one/moons.d/000000c53bc939c1.moon (в Docker-контейнере zerotier).

Содержимое (base64)

moon.b64
fwAAAMU7yTnBAAABnK+hl0TThMZt6mNZ+M7RQUomXAqP14FfhYP31JFStqq/jyPQcZjitqCMpAHybQcKvbtOW+8oLS2CSNAxzpru31jfdZwqwP1gRqQV7UP6nk+nGmCJcToCv+gF4CUe+JiQaLRXpQEPkeSeSREa4W/4DQ/2NmxR0J7qdLPYWmzZhWknkTbrCzr/9qY6M14n+j2IIPrWKO18x06B6Ed1HZ/Z2KIIlcwVAcU7yTnBALm27ZEIiAep3L8bws8Jwp88Q1I52ZzB8iUyNesmZbJ74rWPvgYpHJq5p66QE4l5x3wAkt0LZ3IqD4TSoVcatj0AAQReZ1YDJwkAAA==

Восстановление на новом клиенте

Linux

# 1. Декодировать в правильное имя файла
mkdir -p /var/lib/zerotier-one/moons.d
echo 'fwAAAMU7yTnBAAABnK+hl0TThMZt6mNZ+M7RQUomXAqP14FfhYP31JFStqq/jyPQcZjitqCMpAHybQcKvbtOW+8oLS2CSNAxzpru31jfdZwqwP1gRqQV7UP6nk+nGmCJcToCv+gF4CUe+JiQaLRXpQEPkeSeSREa4W/4DQ/2NmxR0J7qdLPYWmzZhWknkTbrCzr/9qY6M14n+j2IIPrWKO18x06B6Ed1HZ/Z2KIIlcwVAcU7yTnBALm27ZEIiAep3L8bws8Jwp88Q1I52ZzB8iUyNesmZbJ74rWPvgYpHJq5p66QE4l5x3wAkt0LZ3IqD4TSoVcatj0AAQReZ1YDJwkAAA==' \
  | base64 -d > /var/lib/zerotier-one/moons.d/000000c53bc939c1.moon
 
# 2. Проверить (sha256 должен совпасть)
sha256sum /var/lib/zerotier-one/moons.d/000000c53bc939c1.moon
# ожидаем: 76e8a39807413a5b650c61d133d53285492484af0a7d519cf72a86dd3ce76cf6
 
# 3. Перезапустить демон
sudo systemctl restart zerotier-one
 
# 4. Убедиться что moon подхватился
sudo zerotier-cli listmoons

macOS

sudo mkdir -p "/Library/Application Support/ZeroTier/One/moons.d"
echo 'fwAAAMU7yTnBAAABnK+hl0TThMZt6mNZ+M7RQUomXAqP14FfhYP31JFStqq/jyPQcZjitqCMpAHybQcKvbtOW+8oLS2CSNAxzpru31jfdZwqwP1gRqQV7UP6nk+nGmCJcToCv+gF4CUe+JiQaLRXpQEPkeSeSREa4W/4DQ/2NmxR0J7qdLPYWmzZhWknkTbrCzr/9qY6M14n+j2IIPrWKO18x06B6Ed1HZ/Z2KIIlcwVAcU7yTnBALm27ZEIiAep3L8bws8Jwp88Q1I52ZzB8iUyNesmZbJ74rWPvgYpHJq5p66QE4l5x3wAkt0LZ3IqD4TSoVcatj0AAQReZ1YDJwkAAA==' \
  | base64 -D | sudo tee "/Library/Application Support/ZeroTier/One/moons.d/000000c53bc939c1.moon" > /dev/null
 
# Перезапуск
sudo launchctl kickstart -k system/com.zerotier.one
sudo zerotier-cli listmoons

Windows (PowerShell, admin)

$b64 = 'fwAAAMU7yTnBAAABnK+hl0TThMZt6mNZ+M7RQUomXAqP14FfhYP31JFStqq/jyPQcZjitqCMpAHybQcKvbtOW+8oLS2CSNAxzpru31jfdZwqwP1gRqQV7UP6nk+nGmCJcToCv+gF4CUe+JiQaLRXpQEPkeSeSREa4W/4DQ/2NmxR0J7qdLPYWmzZhWknkTbrCzr/9qY6M14n+j2IIPrWKO18x06B6Ed1HZ/Z2KIIlcwVAcU7yTnBALm27ZEIiAep3L8bws8Jwp88Q1I52ZzB8iUyNesmZbJ74rWPvgYpHJq5p66QE4l5x3wAkt0LZ3IqD4TSoVcatj0AAQReZ1YDJwkAAA=='
$dir = 'C:\ProgramData\ZeroTier\One\moons.d'
New-Item -ItemType Directory -Force -Path $dir | Out-Null
[IO.File]::WriteAllBytes("$dir\000000c53bc939c1.moon", [Convert]::FromBase64String($b64))
Restart-Service ZeroTierOneService
& 'C:\Program Files (x86)\ZeroTier\One\zerotier-cli.bat' listmoons

Альтернатива — без файла

Если узел может достучаться до публичных planet'ов ZT, можно обойтись без файла — одной командой:

sudo zerotier-cli orbit c53bc939c1 c53bc939c1

Демон сам найдёт identity moon-узла через planet'ы. Это проще, но требует, чтобы хотя бы при первом запуске planet'ы были достижимы.

selfhosted/zerotier.txt · Последнее изменение: melnoff