Skip to content
lib4uPublic

About

Node Manager for VPN VDS

Resources

Stars

96 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

Repository files navigation

🔥 Не хотите сами поднимать и настраивать ноды? Возьмите VPN, где всё уже настроено. Сервис wpn.me работает на vnm: полная поддержка Amnezia 3.1 и 2.0, а также протоколов VLESS, Hysteria2 и TrustTunnel, устойчивых к блокировкам. Работает даже в условиях «белых списков». 👉 Попробовать wpn.me

vnm — vpn-node-manager

Базовый слой VPN-ноды: одна программа, которая на уровне ядра решает, куда уходит трафик сервера и кого к нему не пускать, — независимо от того, какие VPN-сервисы на нём крутятся (Xray/Remnawave, AmneziaWG, TrustTunnel и что угодно ещё).

Зачем

VPN-сервисы на ноде ничего не знают друг о друге, и правила «куда можно ходить» у каждого свои — или их нет вовсе. Типичная дыра: в профиле Xray российские сайты заблокированы, а клиенты AmneziaWG ходят на них напрямую с IP ноды. vnm закрывает это один раз, для всего сервера:

  • Политика назначений (egress). Списки адресов и доменов из конфига → действие: отправить через выход (например, Cloudflare WARP), заблокировать или выпустить напрямую. Работает для любого трафика: процессов самой ноды, контейнеров и клиентов туннелей.
  • Выход WARP. Своя регистрация Cloudflare WARP на каждой ноде, проверка здоровья, автоматический перевыпуск, если выход умер.
  • Fail-closed. Если выход недоступен, трафик по его правилу отклоняется, а не уходит напрямую. Смерть агента ничего не открывает: правила остаются в ядре.
  • Guard. Блок входящих соединений от адресов из блок-листов (сканеры, подсети госорганизаций) — до ufw, Docker и всех сервисов.
  • Блок торрентов (p2p). Строгие сигнатуры BitTorrent в ядре и вердикты nDPI: загрузка и раздача не идут ни от прокси, ни от клиентов туннелей, рой не достучится до ноды снаружи.
  • Свой DNS-резолвер для доменных списков: адреса доменов попадают в наборы ядра в момент ответа, так что правило срабатывает, даже если сайт живёт не на «своих» IP.
  • Базовая настройка сервера (по желанию): вход только по ключу, fail2ban, сетевые sysctl, swap.

vnm не знает смысла списков: «ru_ip» или «corp» — это только имена в конфиге. Что куда отправлять, целиком задаётся в /etc/vnm/config.yaml.

Как это устроено

                 ┌──────────────── vnm-agent ─────────────────┐
config.yaml ───▶ │ списки (скачать/проверить) → план → nftables│──▶ ядро: таблица inet vnm,
                 │ здоровье выходов, перевыпуск, метрики       │     ip rule, маршруты выходов
                 └─────────────────────────────────────────────┘
vnm-dns   — резолвер: ответы по доменам списков кладёт в наборы nftables
vnm-boot  — при загрузке восстанавливает последнее рабочее состояние с диска, до подъёма сети
vnm (CLI) — установка, переключение режимов, статус, диагностика
  • Решение принимается один раз, на первом пакете нового соединения, и запоминается в метке conntrack. Ответы клиентам никогда не перенаправляются.
  • Вся политика живёт в одной таблице inet vnm, которой владеет агент. Чужие таблицы (ufw, Docker, iptables других сервисов) vnm не читает и не трогает.
  • Агент раз в несколько секунд сверяет ядро с планом и возвращает всё, что изменили руками (это считается дрейфом и видно в статусе и метриках).

Режимы и безопасные переключения

Режим Что происходит
observe всё классифицируется и считается, трафик не меняется — «что было бы»
enforce рабочий режим
off политика снята

Выход egress из enforce (в observe или off) выпускает трафик списков с IP ноды, поэтому требует явного -allow-leak — случайно открыть утечку командой нельзя. Egress и guard переключаются независимо. Любое переключение можно сделать временным: -auto-rollback 5m — если за 5 минут его не подтвердить из новой SSH-сессии, vnm сам вернёт прежний режим. Так же устроена настройка SSH в base: потеряли доступ — через 5 минут всё откатится.

Блокировка торрентов (p2p)

Хостеры закрывают серверы за раздачу торрентов, а блок bittorrent в Xray ловит только открытое рукопожатие. vnm режет BitTorrent на уровне сети, для всех сервисов ноды сразу. Подробно — docs/vpn-node-manager-p2p-tz.md.

Два слоя:

  1. Сигнатуры в ядре — строгое совпадение полей заголовка, без наивных префиксов (те ловят TURN/WebRTC):
    • utp_syn — uTP ST_SYN: заголовок uTP открыт даже при шифровании MSE, и без SYN соединение с пиром не возникает;
    • dht — запросы и ответы DHT (d1:ad2:id20: / d1:rd2:id20:);
    • udp_tracker — connect к UDP-трекеру (magic 0x41727101980);
    • bt_handshake — открытое рукопожатие \x13BitTorrent protocol по TCP.
  2. nDPId — отдельный демон (vnm-ndpid) с libnDPI. Пассивно читает копии пакетов на всех интерфейсах (кроме DNS и 80/443/853) и сообщает агенту вердикты по потокам. Ловит то, чего не видно в одном пакете: шифрованный BitTorrent, uTP посреди потока. Агент кладёт пира из вердикта в набор p2p_peers на peer_ttl — дальше с ним не говорит никто на ноде. Если клиент туннеля за window обращается к threshold разным пирам, он сам попадает в p2p_ban на ttl.

Где проверяется (таблица inet vnm, приоритет −155: после guard, до egress — отрезанный поток не тратит WARP):

Цепочка Хук Что режет
p2p_local output исходящее процессов ноды (прокси)
p2p_tunnel → p2p prerouting исходящее клиентов туннелей (AmneziaWG и т.п.)
p2p_tunnel → p2p_in prerouting, с аплинков входящее от пиров: UDP прокси принимает пакеты от любого адреса, и рой сам стучится в порт, который прокси открыл клиенту
p2p_banned prerouting всё (или всё, кроме DNS и веба) от забаненного клиента туннеля

Никогда не трогаются: ответы на соединения, адреса из exempt, DNS и порты 80/443. Наборы пиров и банов переживают замену таблицы и перезапуск агента. Пользователю прокси бан не грозит — у ноды нет его адреса: режутся пиры и пакеты торрента, остальной VPN у него работает.

Включение:

# nDPId в комплект не входит (GPL-3.0, отдельный бинарник): nDPId 1.7.0 + libnDPI 6.1,
# собранный статически, кладётся сюда; без него работает только слой сигнатур
scp nDPId root@NODE:/usr/local/lib/vnm/nDPId

# в /etc/vnm/config.yaml (полный пример — configs/vnm.yaml):
#   p2p:
#     mode: off
#     signatures: [utp_syn, dht, udp_tracker, bt_handshake]
#     ndpi: {}
ssh root@NODE 'systemctl enable --now vnm-ndpid'

ssh root@NODE 'vnm p2p observe -auto-rollback 5m'   # считать, ничего не резать
ssh root@NODE 'vnm p2p confirm'
ssh root@NODE 'vnm status | grep ^p2p'              # что было бы отрезано
ssh root@NODE 'vnm p2p enforce -auto-rollback 5m'   # проверить сервисы, затем confirm

vnm status показывает счётчики сигнатур, работает ли nDPId, сколько найдено потоков, отвергнуто пиров и забанено клиентов; journalctl -u vnm-agent | grep "p2p peer" — каждый вердикт с пиром.

Что входит в комплект

Что Где на ноде
Бинарник vnm (статический, CLI + агент + резолвер) /usr/local/bin/vnm
Конфиг политики /etc/vnm/config.yaml (при установке кладётся configs/vnm.yaml, если файла нет)
Юниты vnm-agent, vnm-boot, vnm-dns, vnm-ndpid /etc/systemd/system/ (шаблоны в init/)
nDPId для p2p (не входит в репозиторий, кладётся отдельно) /usr/local/lib/vnm/nDPId
Выход WARP: аккаунт и конфиг /etc/vnm/exits/warp/ (права 600)
wgcf (пин версии и sha256) /usr/local/lib/vnm/wgcf
Состояние агента, кеши списков, бэкапы миграции /var/lib/vnm/
Метрики для node_exporter (textfile) /var/lib/node_exporter/textfile_collector/vnm.prom

Установщик сам ставит нужные пакеты (nftables, fail2ban для base) и создаёт системного пользователей vnm-dns для резолвера и vnm-ndpid для nDPId.

Требования

  • Ubuntu 22.04 / 24.04 / 26.04, Debian 12 / 13 или AlmaLinux 9 / 10, архитектура amd64. На других ОС установщик отказывает, ничего не меняя (Ubuntu 20.04 не поддерживается: старый nftables).
  • root, systemd, ядро с WireGuard (для выхода WARP).
  • Хотя бы один SSH-ключ в authorized_keys root, если ставится base (без ключа base откажет, чтобы не отрезать доступ).
  • Исходящий доступ к GitHub (списки geo) и к Cloudflare (регистрация WARP).

Сборка

make build        # bin/vnm, статический бинарник, версия = git describe
make check        # fmt + vet + тесты — обязательно перед выкаткой на ноду
make test-short   # только юнит-тесты, без network namespace

Полный make test включает стенд test/flowstand — настоящие правила в непривилегированных network namespace (нужны unshare и nft, без них стенд пропускается).

Установка на ноду

# 1. Бинарник и конфиг
scp bin/vnm root@NODE:/usr/local/bin/vnm
ssh root@NODE 'chmod 755 /usr/local/bin/vnm && mkdir -p /etc/vnm'
scp config.yaml root@NODE:/etc/vnm/config.yaml   # или без него — встанет configs/vnm.yaml

# Перед установкой впишите в exempt адреса, которые управляют нодой (панель, мониторинг):
# в configs/vnm.yaml там стоит документационный 203.0.113.10 — он никого не освобождает.

# 2. Установка: base + WARP + юниты. Режим берётся из конфига (начинайте с observe).
ssh root@NODE 'vnm install'
#   -skip-base          не трогать SSH, fail2ban, sysctl и swap
#   -license KEY        сразу применить ключ WARP+
#   -trust CIDR,…       адреса, которые fail2ban никогда не банит

# 3. Подтвердить SSH-настройку base — ИЗ НОВОЙ SSH-сессии, в течение 5 минут
ssh root@NODE 'vnm base confirm'

# 4. Проверить
ssh root@NODE 'vnm status; vnm doctor'
ssh root@NODE 'vnm test ya.ru; vnm test 1.1.1.1'   # что нода делает с назначением

Включение egress и guard

ssh root@NODE 'vnm egress enforce -auto-rollback 5m'
# проверка: трафик по правилу идёт через выход, остальной — с IP ноды, сервисы живы
ssh root@NODE 'curl -s https://nplus1.ru/cdn-cgi/trace | grep warp'   # warp=on
ssh root@NODE 'vnm egress confirm'                                     # из новой сессии

ssh root@NODE 'vnm guard enforce -auto-rollback 5m'
# проверка: SSH, порты сервисов, связь с панелью
ssh root@NODE 'vnm guard confirm'                                      # из новой сессии

Не подтвердили — через 5 минут режим вернётся сам. Передумали раньше — vnm egress rollback / vnm guard rollback.

Если на сервере уже был WARP

Установщик находит ручной WARP (wg-quick@warp, свои ip rule на метку 0xca6c, wtm), сохраняет его в /var/lib/vnm/migration/<дата>/, сносит и регистрирует свой. Правило, которое он не может однозначно отнести к старому WARP, — остановка с описанием, решение за оператором. На время замены (1–2 минуты) трафик по правилам выхода отклоняется, остальной не затрагивается.

Конфиг

Разделы /etc/vnm/config.yaml (полный пример с комментариями — configs/vnm.yaml):

Раздел Что задаёт
mode режим egress: observe / enforce / off
geo откуда брать geoip.dat / geosite.dat для списков вида geoip:…, geosite:…
dns порт резолвера и вышестоящие DNS
exits выходы: интерфейс, конфиг, запасные endpoints, проверка здоровья, команда перевыпуска
lists списки: ip (geoip, url:, file:), domain, suffix, extra_cidr, границы размера, частота обновления
policy правила по порядку, первое совпадение побеждает: lists → action (exit:<имя>, block, direct) + fallback на случай мёртвого выхода
guard режим и правила блока входящих: lists → drop/reject, log
p2p блок торрентов: режим, сигнатуры, ndpi (вердикты nDPId), ban (бан клиентов туннелей по «рою»)
exempt адреса, которые не трогают ни политика, ни guard, ни p2p (панель, управление)

Пример правила:

policy:
  - lists: [ru_ip, ru_domain, ru_suffix]
    action: exit:warp
    fallback: block

Конфиг читается строго: неизвестное поле — ошибка, и в силе остаётся последний валидный. Поэтому при обновлении сначала выкатывается новый бинарник, потом конфиг с новыми полями.

Команды

Команда Что делает
vnm install [-skip-base] [-license KEY] [-trust …] полная установка ноды
vnm base apply / vnm base confirm базовая настройка / подтвердить SSH-изменения
vnm warp install / plus KEY / reissue регистрация WARP / ключ WARP+ / новая регистрация
vnm egress observe|enforce|off [-allow-leak] [-auto-rollback 5m] режим политики назначений
vnm guard observe|enforce|off [-auto-rollback 5m] режим guard
vnm p2p observe|enforce|off [-auto-rollback 5m] режим блока торрентов
vnm egress|guard|p2p confirm|rollback оставить или откатить временное переключение
vnm status что агент увидел на последнем проходе: режимы, выходы, списки, счётчики, ошибки
vnm test IP|DOMAIN как нода поступит с этим назначением
vnm doctor сквозная проверка ноды
vnm lists update скачать списки сейчас
vnm agent / vnm boot / vnm dns serve то, что запускают юниты
vnm version версия сборки

Метрики

Агент пишет файл в формате Prometheus для textfile-коллектора node_exporter. Главное:

  • vnm_exit_healthy, vnm_exit_alert — жив ли выход и не мёртв ли он дольше 15 минут;
  • vnm_policy_applied, vnm_drift_total, vnm_apply_errors_total — стоит ли политика в ядре;
  • vnm_connections_total — сколько соединений классифицировано каждым правилом;
  • vnm_guard_refused_total{list} — сколько отбил guard (в observe — «отбил бы»);
  • vnm_list_entries, vnm_list_age_seconds, vnm_list_failed — состояние списков;
  • vnm_resolver_up — работает ли резолвер;
  • vnm_p2p_mode, vnm_p2p_refused_total{signature} — режим и что отрезали сигнатуры;
  • vnm_p2p_ndpi_up, vnm_p2p_detections_total, vnm_p2p_peers_total, vnm_p2p_bans_total — nDPId пишет, сколько найдено потоков, отвергнуто пиров, забанено клиентов.

node_exporter в комплект не входит: чтобы метрики собирались, его нужно поставить на ноду отдельно.

Известные особенности

  • Монолитное ядро без modprobe (образы некоторых хостеров): base падает на шаге sysctl — ставить с -skip-base, сетевые sysctl задать вручную. Там же у nft нет именованных счётчиков: политика работает, но vnm status не покажет счётчики.
  • ufw / firewalld: установщик открывает порт резолвера (5353) и кладёт интерфейс выхода в зону firewalld, если фаервол уже включён. Включили ufw после vnm — откройте 5353 сами (vnm doctor это покажет).
  • IPv6: выходы только IPv4. Резолвер отдаёт домены списков с выходом без AAAA, а литеральные IPv6-адреса из таких списков блокируются.

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

  • docs/vpn-node-manager-tz.md — основное ТЗ: инварианты, политика, выходы, агент, режимы.
  • docs/vpn-node-manager-installer.md — установщик: base и WARP, миграция со старого WARP.
  • docs/vpn-node-manager-dns-tz.md — резолвер доменных списков.
  • docs/vpn-node-manager-guard-tz.md — guard.
  • docs/vpn-node-manager-p2p-tz.md — блок торрентов: сигнатуры, nDPId, бан клиентов.
  • docs/vpn-node-manager-tests.md — приёмочные тесты.
  • docs/vpn-node-manager-logging-tz.md — журнал событий (в разработке).

About

Node Manager for VPN VDS

Resources

Stars

96 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages