mistgate Документация

Требования

Что нужно серверу панели, серверам нод и машине для сборки, и что агент меняет на ноде.

На этой странице

Для Mistgate нужен один Linux-сервер под панель, один или несколько Linux-серверов под ноды, доменное имя и машина, на которой вы соберёте бинарники. Бинарных релизов пока нет, поэтому сборка — из исходников.

Сервер панели#

Что Требование
Система Linux на amd64 или arm64. systemd, чтобы держать mistgate serve запущенным (пример юнита — в Установке панели).
Доступ root для установки. Работающей панели нужно только занять TCP 443 и 80 и писать в свой каталог данных.
Домен Имя хоста, у которого A-запись (и AAAA, если есть IPv6) указывает на сервер, например panel.example.com.
Входящие порты TCP 443: сайт-ширма, подписки, страницы пользователей, админка (в режимах с секретным путём и секретным хостом) и агенты нод. TCP 80, если сертификат панели выдаёт Let's Encrypt. Больше ничего, если вы не выбрали отдельный порт для админки или агентов.
Исходящие Let's Encrypt по HTTPS, если вы им пользуетесь. Порты ваших серверов на нодах: панель проверяет каждый сервер как клиент (Hysteria2 по UDP, AmneziaWG по UDP). Cloudflare по HTTPS, если вы регистрируете аккаунты WARP или включаете капчу Turnstile.
Диск Каталог данных, по умолчанию /var/lib/mistgate: одна база SQLite, мастер-ключ и несколько небольших файлов.
Другие программы Не нужны. Панель — один статический бинарник и других программ не запускает.
Важно

держите панель на отдельном сервере. Нода на том же хосте стала бы спорить с панелью за TCP 443 (Hysteria2 по умолчанию держит там HTTPS-сайт) и TCP 80.

Серверы нод#

Что Требование
Система Linux с systemd: Ubuntu 22.04 и новее или Debian 12 и новее. amd64 или arm64.
Доступ root по SSH. mistgate-node install запускается от root, и агент работает от root, но с урезанным набором прав.
Адрес Публичный IPv4. Клиенты подключаются к адресу ноды: к домену, который указывает на сервер, или прямо к IP.
nftables Команда nft (по умолчанию есть в Debian 12 и Ubuntu 22.04+). Через неё агент управляет своими правилами. Прыжкам по портам нужен redirect в семействе inet, он есть в ядрах начиная с 5.2.
Устройство TUN /dev/net/tun для AmneziaWG в userspace и для WARP. На контейнерных VPS (OpenVZ, LXC) включите TUN в панели хостера.
Часы Синхронизированы по NTP. Агент сообщает, если его часы расходятся с панелью больше чем на 30 секунд, и доктор проверяет это в time_sync.
Входящие порты UDP-порт каждого сервера на ноде: у Hysteria2 по умолчанию 443, профилю AmneziaWG достаётся случайный порт от 10000 до 60000. Диапазон прыжков по портам у профиля Hysteria2, если вы его включили (от 1024 и не больше 20 000 портов). TCP 443 для HTTPS-сайта, который Hysteria2 показывает всем, кроме своих клиентов, и для Let's Encrypt. TCP 80 для Let's Encrypt, если порт свободен.
Исходящие TCP к панели (обычно 443). Let's Encrypt, DNS и серверы WARP у Cloudflare, если нода пользуется WARP.
Управляющий порт Не нужен. Агент сам подключается к панели, и на ноде ничего не должно принимать соединения от панели.

Полезно знать:

  • IPv6 не обязателен. Нода без IPv6 работает по IPv4. Хуже, когда глобальный IPv6-адрес есть, а исходящие соединения по IPv6 не проходят: приложения, получившие AAAA-ответ, зависают. Проверка доктора ipv6 об этом предупреждает.
  • Контейнеры. На OpenVZ или LXC агент не может выставить свои значения sysctl (он пишет об этом в лог и работает дальше), а модуль ядра AmneziaWG там не установить. Userspace-вариант работает, если включён TUN.
  • Модуль ядра AmneziaWG. Не обязателен. По умолчанию AmneziaWG работает в userspace, и модуль ему не нужен. По запросу агент (или mistgate-node awg prepare-kernel) собирает модуль: на Ubuntu из PPA Amnezia, на Debian из исходников. Для этого нужны apt и systemd, а контейнер и Secure Boot не подходят.
  • Лучше чистый хост. Доктор сообщает, что может мешать: другие VPN-панели и их контейнеры, Xray, старые интерфейсы WireGuard, чужие правила NAT в nftables и политика DROP в цепочке FORWARD от Docker (она ломает пересылку трафика AmneziaWG).

Сборка из исходников#

Инструмент Версия
Go 1.27. В go.mod указан тулчейн (go1.27.1); при GOTOOLCHAIN=auto (так по умолчанию) более старый Go скачает его сам.
Node.js 22 или новее (веб-админка собирается и встраивается в бинарник панели).
pnpm 10.
make и POSIX-оболочка В Windows — Git Bash или WSL.
git make build записывает в бинарники версию (git describe) и время коммита (git log). Без git версия будет 0.0.0-dev, а время сборки — 0.
Доступ в интернет Для модулей Go и пакетов npm.

make build собирает статические бинарники для Linux (CGO_ENABLED=0) под обе архитектуры:

sh
make build
# bin/mistgate-linux-amd64       bin/mistgate-node-linux-amd64
# bin/mistgate-linux-arm64       bin/mistgate-node-linux-arm64
Внимание

агенты нод обновляются сами, только если собраны с вашим ключом релиза (RELEASE_KEY=<публичный ключ> make build). Ноду, установленную из сборки без ключа, один раз придётся обновить вручную. Если собираетесь пользоваться подписанными обновлениями, сделайте ключ до первой сборки — см. Обновления.

DNS и сертификаты#

  • Панель. Направьте имя панели прямо на сервер, без CDN и прокси перед ним. Агенты нод сверяют собственный CA панели, а Let's Encrypt проверяет домен на самом сервере; через прокси, который сам завершает TLS, не работает ни то ни другое.
  • Сертификат панели. Либо панель сама получает его у Let's Encrypt (serve --acme-domain), либо вы даёте ей свои файлы сертификата (serve --tls-cert и --tls-key). Подробнее — в Установке панели.
  • Секретный хост админки. Если админка живёт на секретном имени хоста, этому имени нужна своя DNS-запись и сертификат, который его покрывает. Сертификат Let's Encrypt публикует свои имена в открытых журналах Certificate Transparency; ваш собственный wildcard-сертификат оставляет секретное имя за их пределами.
  • Точка подключения агентов. Ей не нужны ни DNS-запись, ни публичный сертификат. Агенты подключаются к адресу панели с секретным именем SNI (случайная метка в домене панели), и на это имя панель отвечает сертификатом от своего CA.
  • Ноды. Серверу Hysteria2 с сертификатом Let's Encrypt нужен домен, у которого A-запись указывает на ноду: адрес ноды или «Домен (SNI)» в профиле. Нода, у которой есть только IP, работает с самоподписанным сертификатом (с пином). AmneziaWG сертификат не нужен.

Что агент меняет на ноде#

Агент меняет только то, что перечислено ниже, и только свои объекты: он не трогает чужие таблицы nftables, никогда не перенаправляет порты ниже 1024 и не даёт диапазону прыжков по портам задеть порты sshd.

Что Где Когда
Бинарник агента /usr/local/bin/mistgate-node (install --bin меняет путь). Самообновление кладёт рядом <бинарник>.new и <бинарник>.prev. mistgate-node install, самообновление
Служба /etc/systemd/system/mistgate-node.service, включена и запущена. mistgate-node install
Каталог состояния /var/lib/mistgate-node (права 0700, файлы 0600): ключ и сертификат ноды, CA панели, адрес панели, последнее применённое состояние, сертификаты её серверов, отметки обновления. enroll, потом агент
sysctl /etc/sysctl.d/90-mistgate.conf: net.core.default_qdisc = fq и net.ipv4.tcp_congestion_control = bbr; те же значения сразу выставляются в работающем ядре. при каждом запуске агента
journald /etc/systemd/journald.conf.d/90-mistgate.conf: SystemMaxUse=200M, RuntimeMaxUse=200M. Если файл изменился, journald перезапускается. при каждом запуске агента
Файрвол: защита SSH и прыжки по портам Таблица nftables inet mistgate_node. при каждом запуске агента и при смене диапазонов прыжков
AmneziaWG Интерфейсы mgawg<порт>, таблица nftables inet mistgate_awg (NAT для клиентов, ограничение MSS, никакого трафика между клиентами, через туннель с ноды доступен только ping до адреса туннеля). Включается пересылка IPv4; пересылка IPv6 — если у туннеля есть IPv6, причём интерфейсы с accept_ra=1 сначала переводятся на accept_ra=2, чтобы хост не потерял собственный IPv6. Значения пересылки выставляются только в работающем ядре. пока на ноде работает сервер AmneziaWG
WARP Интерфейс mgwarp, таблица маршрутизации 51820 с правилами на приоритетах 90 и 110, таблица nftables inet mistgate_warp. пока у ноды есть WARP
Резолвер /etc/systemd/resolved.conf.d/90-mistgate.conf (при systemd-resolved) или переписанный /etc/resolv.conf, а оригинал сохраняется как /etc/resolv.conf.mistgate.bak. только если вы применили исправление резолвера из доктора
Размер журнала journalctl --vacuum-size=200M --vacuum-time=7d. только если вы применили это исправление из доктора
Модуль ядра AmneziaWG Пакеты apt, PPA Amnezia на Ubuntu или сборка из исходников на Debian, /etc/modules-load.d/amneziawg.conf. Работает как временный юнит mistgate-awg-prepare. только по вашему запросу
Важно

защита SSH ограничивает новые подключения к портам sshd с одного адреса (для IPv6 — с одной сети /64): сначала 10 подряд, потом 6 в минуту. Открытые сессии она не трогает, никого не банит, на loopback не действует, а при переполнении своей таблицы перестаёт срабатывать, чтобы не запереть вас снаружи. Инструменты, которые разом открывают много SSH-подключений с одного адреса, всё же могут в неё упереться. Порты sshd агент находит через sshd -T, файлы конфигурации sshd и ssh.socket; если ничего не нашёл, берёт 22.

Юнит службы#

mistgate-node install пишет юнит сам и подбирает лимиты под память хоста. Главное в нём:

Настройка Значение
Запуск mistgate-node run --state-dir /var/lib/mistgate-node
Перед запуском защита от падений в цикле: если новая версия после обновления падает три раза подряд, возвращается прежний бинарник
После каждой остановки mistgate-node cleanup-net: убирает интерфейсы AmneziaWG и WARP, маршруты и правила WARP и их таблицы nftables, чтобы упавший агент не оставил сломанную маршрутизацию (при запуске агент всё вернёт)
Перезапуск Restart=on-failure через 5 с; код выхода 78 (нода не подключена или выведена) перезапуска не вызывает
Память GOMEMLIMIT около 60% RAM (не меньше 64 МиБ), MemoryHigh около 70%, MemoryMax около 85%; LimitNOFILE=65536
Права работает от root, но только с CAP_NET_ADMIN и CAP_NET_BIND_SERVICE, NoNewPrivileges=yes
Файлы ProtectSystem=strict: писать можно только в каталог состояния, каталог бинарника, /etc/sysctl.d и /etc/systemd/journald.conf.d
Устройства кроме стандартных псевдоустройств — только /dev/net/tun
Прочее ProtectHome, PrivateTmp, SystemCallFilter=@system-service, UMask=0077 и остальная обычная изоляция systemd

Что убирает вывод ноды из флота и как почистить хост вручную — в разделе «Удаление ноды» на странице Добавление ноды.

Править страницу на GitHub