Skip to content

anfixit/routerus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

routerus

Автоматический деплой VPN-ноды на базе Remnawave + Xray-core за одну команду

VLESS · Reality · steal_oneself · транспорт TCP/Vision, XHTTP или оба сразу

Shell Ubuntu Xray-core Remnawave ShellCheck License: MIT

Возможности · Быстрый старт · Как это работает · Настройка панели · Обновление · FAQ


О проекте

routerus — интерактивный bash-скрипт, который на чистой Ubuntu 24.04 разворачивает готовую к работе VPN-ноду для Remnawave Panel: хардит систему, поднимает Xray-core с VLESS + Reality, маскирует ноду под легитимный сайт и печатает готовый JSON для вставки в панель. Одна нода — один домен.

Скрипт идемпотентен: повторный запуск не ломает уже настроенную ноду, а на живой ноде пропускает apt upgrade, чтобы не оборвать трафик.

Возможности

  • VLESS + Reality — TLS-маскировка без собственного сертификата; DPI и пробберы видят легитимный TLS-хендшейк.
  • Три режима транспорта — выбор цифрой 1/2/3 при запуске (Enter = 1):
    • 1 tcp (по умолчанию) — RAW + xtls-rprx-vision, полная совместимость с любым клиентом, включая podkop/Nikki на mihomo;
    • 2 xhttpmode=packet-up: дробит upload под API-запросы, устойчив к поведенческому DPI на мобильных сетях РФ;
    • 3 both — оба inbound на одной ноде (tcp:443 + xhttp:<port>) с общим privateKey; подписка отдаёт обе ссылки, podkop берёт tcp.
  • steal_oneself — Reality dest указывает на собственный nginx на том же сервере: SNI резолвится на наш IP → настоящий сайт → всё легитимно.
  • Фейковый сайт — генератор бизнес-лендинга, детерминированный от хэша домена (на ре-запуске не меняется — фингерпринт стабилен).
  • Хардинг из коробки — SSH key-only на нестандартном порту с замаскированным ssh.socket, fail2ban, sysctl (BBR, TCP-буферы, SYN-flood protection), UFW, автообновления безопасности.
  • Docker из подписанного репозитория — установка через официальный apt-репо с GPG-проверкой пакетов, а не curl … | sh; заодно гарантирует docker compose v2.
  • Безопасность секретов — приватный ключ Reality не попадает в лог (Config Profile пишется в config-profile.json 600 и на терминал); лог, .env и keys.txt с правами 600, фейк-сайт 644 (иначе nginx отдал бы 403).
  • Zero-downtime SSL — выпуск и продление через webroot, nginx не гасится; renewal-hook пересоздаёт контейнер ноды, чтобы Xray подхватил новый сертификат.
  • Эксплуатация — watchdog контейнера, автообновление geo-списков с валидацией целостности, ротация docker-логов, опциональный агент Beszel.

Требования

Компонент Версия / условие
ОС чистая Ubuntu 24.04+ с выделенным IPv4
Порт 443 свободен до установки (Xray слушает напрямую)
Домен A-запись указывает на IP сервера
Remnawave Panel 2.8.0+
Node / Xray Node 2.8.0+ (Xray-core 26.6.27 в образе)
Права root на время установки

Быстрый старт

1. Домен

Купи домен (.ru от 129 ₽/год) и настрой DNS A-запись на IP сервера.

2. Запуск

ssh root@IP_СЕРВЕРА
bash <(wget -qO- https://raw.githubusercontent.com/anfixit/routerus/main/deploy-remnanode.sh)

Скрипт спросит: домен, публичный SSH-ключ, имя ноды, транспорт. Для ключа он печатает команды получения .pub под macOS/Linux (cat ~/.ssh/id_ed25519.pub) и Windows (Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub в PowerShell, type %USERPROFILE%\.ssh\id_ed25519.pub в cmd). Транспорт выбирается цифрой 1/2/3 (Enter = 1/tcp); для both дополнительно спрашивается порт xhttp.

Опциональные переменные окружения:

# пин образа ноды (по умолчанию remnawave/node:latest)
REMNANODE_IMAGE=remnawave/node:2.8.0 bash deploy.sh
# пин образа для генерации ключей (по умолчанию :latest)
XRAY_KEYGEN_IMAGE=ghcr.io/xtls/xray-core:26.6.27 bash deploy.sh
# email для Let's Encrypt (по умолчанию регистрация без email)
CERTBOT_EMAIL=you@example.com bash deploy.sh

3. Настройка в панели

Скрипт печатает готовый JSON и пошаговый чек-лист (см. ниже). После ввода SECRET_KEY из панели контейнер поднимается автоматически.

4. Проверка

ssh -p 2810 admin@IP_СЕРВЕРА     # из НОВОГО терминала — доступ жив?
# нода в панели зелёная? клиент → обнови подписку → пинг есть?

Как это работает

Клиент (Happ / v2rayNG / podkop-Nikki на mihomo)
    │
    ▼
Xray :443  (VLESS + Reality + TCP/Vision | XHTTP)   [+ xhttp:<port> в режиме both]
    │
    ├── Reality-клиент ──────────► VPN-туннель ──► интернет
    │
    └── Не-Reality (DPI / проббер)
            │
            ▼
        nginx :8443  (настоящий сайт с SSL)  ← steal_oneself

Reality проверяет клиента по x25519-ключу и shortId. Легитимный трафик уходит в туннель; всё остальное (DPI-зонды, случайные боты) Reality прозрачно проксирует на локальный nginx с настоящим сайтом — сервер выглядит как обычный веб-хостинг.

Фазы установки

Скрипт выполняет 18 фаз (0–17): проверки окружения (включая свободный :443) → ввод параметров → зависимости и Docker (подписанный apt-репо) → хардинг SSH → fail2ban → sysctl → nginx :80 + SSL (webroot) → nginx-fallback :8443 → фейковый сайт → генерация ключей и JSON → пауза на настройку панели → geo-файлы → запуск remnawave-node → автообслуживание → watchdog → UFW → Beszel → итоговая сводка.

Открываемые порты

Порт Назначение
2810 SSH (key-only)
443 Xray Reality (VLESS tcp/xhttp)
<port> Xray Reality XHTTP (только режим both)
80 HTTP-редирект + ACME challenge
2222 Remnawave node API
45876 Beszel agent (опционально)

nginx-fallback слушает 127.0.0.1:8443 (только loopback — через него ходит Reality), наружу не публикуется.

Настройка в панели Remnawave

Актуально для Panel 2.8.0. Учти изменения хостов в этой версии: единый tag заменён на массив tags[]; allowInsecure убран; фиксированные значения fingerprint больше не enum — это свободная строка (chrome по-прежнему валиден); ALPN поддерживает h2, h3 и комбинации.

  1. Config Profiles → Create — вставить JSON из вывода скрипта.
  2. Nodes → Create — Address = IP сервера, Port 2222, привязать профиль, включить все inbound, скопировать SECRET_KEY обратно в скрипт.
  3. Hosts → Create — Address и SNI = домен, Fingerprint chrome:
    • Flow задавать не нужно — для VLESS + Reality + TCP панель добавляет xtls-rprx-vision автоматически;
    • tcp-хост: Port 443, ALPN не задавать;
    • xhttp-хост: Port 443 (или <port> в режиме both), ALPN h2;
    • в режиме both создать два хоста — по одному на каждый inbound.
  4. Internal Squads → Default-Squad — добавить все inbound ноды (без этого нода не попадёт в подписку).

Проверь готовую ссылку подписки: для tcp-инбаунда в ней должно быть &flow=xtls-rprx-vision. Если flow не появился — в Config Profile поменяй "network": "tcp" на "network": "raw" (в Xray 26.x это одно и то же).

Клиент и селективная маршрутизация

TCP + Vision выбран по умолчанию ради маршрутизации на роутере: ядро mihomo (podkop / Nikki) парсит ссылку подписки Remnawave с flow=xtls-rprx-vision без доработок.

Начиная с Panel/Node 2.8.0 Remnawave умеет генерировать XHTTP- и Hysteria2-подписки и для клиентов на ядре Mihomo (полный набор xmux, download-settings и padding). Если твоя сборка podkop собрана со свежим mihomo — XHTTP на роутере становится реально применим; проверяй на своей прошивке перед раскаткой на флот.

В режиме both подписка содержит и tcp-, и xhttp-ссылку — приложения (Happ) видят обе, а роутер берёт tcp. Раскатка подписки на роутер и авто-выбор быстрейшего сервера живут в отдельных инструментах (podkop-sub, fleet_deploy) и в этот репозиторий не входят.

Обновление нод

Ядро Xray живёт внутри docker-образа remnawave/node, а Reality-конфиг хранится в панели, не на ноде. Поэтому при выходе новой версии ядра (например, Node 2.8.0 → Xray-core 26.6.27) полная пересборка не нужна — достаточно подтянуть свежий образ. Хардинг, geo, nginx и SSH не затрагиваются.

Достаточно подтянуть свежий образ. На ноде:

cd /opt/remnanode && docker compose pull && docker compose up -d

Хардинг, geo, nginx, SSH и ключи не затрагиваются. Чтобы зафиксировать конкретную версию, поправь строку image: в /opt/remnanode/docker-compose.yml перед pull (по умолчанию remnawave/node:latest; тег задаётся и при первом деплое через REMNANODE_IMAGE).

Панель мониторит только API-порт 2222 — нода может показываться «зелёной» при мёртвом VPN-инбаунде. После обновления проверь реальный inbound: ss -tlnp | grep -E ':(443|8444)' на ноде.

Эксплуатация

Задача Где
Ключи Reality /opt/remnanode/keys.txt (chmod 600)
Лог установки /var/log/deploy-remnanode.log (chmod 600)
Обновление geo cron 0 3 * * *update-geo.sh (с валидацией)
Перезапуск при падении cron */5watchdog.sh
Обновление образа ноды docker compose pull && up -d в /opt/remnanode
Логи ноды docker logs remnawave-node

Безопасность

  • Приватный ключ Reality печатается только на терминал; Config Profile с ключом сохраняется в /opt/remnanode/config-profile.json (600) и не пишется в лог.
  • Лог установки, .env и keys.txt создаются с правами 600; фейк-сайт — 644 (иначе nginx-воркер отдаёт 403 и ломает маскировку).
  • SSH: только по ключу, root запрещён, нестандартный порт, ssh.socket замаскирован, sshd -t перед рестартом (защита от локаута), fail2ban.
  • SSL выпускается и продлевается через webroot без остановки nginx; продление пересоздаёт контейнер ноды (renewal-hook), чтобы Xray подхватил новый cert.
  • Docker ставится из официального apt-репозитория с GPG-проверкой пакетов (не curl … | sh); проверяется наличие docker compose v2.
  • Существующие daemon.json / cli.ini / sshd_config резервируются перед перезаписью.

Нашёл проблему безопасности? Не открывай публичный issue — см. SECURITY.md.

FAQ

Почему TCP по умолчанию, а не XHTTP? TCP + Vision совместим со всеми клиентами и стабилен. XHTTP (packet-up) устойчивее к поведенческому DPI на мобильных сетях, но с частью клиентов на mihomo исторически менее надёжен — хотя в Panel 2.8.0 поддержка Mihomo+XHTTP уже появилась. Выбор остаётся за тобой при запуске.

Зачем режим both? Одна нода отдаёт и tcp (для podkop/флота), и xhttp (для клиентов за жёстким DPI) одновременно, с общим ключом.

Не нашёл поле Flow в панели. Его там и нет. Remnawave добавляет flow: xtls-rprx-vision автоматически для VLESS + Reality + TCP. Проверить можно в готовой ссылке подписки.

Обновилось ядро — надо пересобирать ноды? Нет. Ядро внутри docker-образа. На ноде: cd /opt/remnanode && docker compose pull && docker compose up -d. Reality-конфиг, ключи и хардинг не тронутся.

Можно ли запускать deploy повторно? Да, скрипт идемпотентен: пользователь, ключи, конфиги переиспользуются, apt upgrade на живой ноде пропускается, geo и контейнер обновляются.

Нода не появилась в клиенте. Проверь шаг 4 в панели — inbound должен быть добавлен в Internal Squad, иначе он не попадёт в подписку.

Версии

Версия Изменения
v3.9 UX + аудит: выбор транспорта цифрой 1/2/3, SSH-примеры для Windows/Linux/macOS, Docker из подписанного apt-репо (+ гарантия compose v2), проверка свободного :443, head -1 в парсинге ключа, устойчивая fallback-цепочка keygen, check_internet без ICMP-маскировки, поллинг старта контейнеров вместо sleep, 45876 в списке занятых портов
v3.8 Аудит: privateKey убран из лога (JSON → config-profile.json 600), SSH-хардинг в 00-hardening.conf (пароли реально off), nginx-fallback только loopback + порт убран из UFW, фикс зависания phase2 (needrestart/lock), renewal пересоздаёт ноду, обязательный geoip.dat, bittorrent → BLOCK, пин образа REMNANODE_IMAGE
v3.7 Аудит: chmod фейк-сайта (фикс 403), mask ssh.socket (фикс падений SSH), zero-downtime SSL (webroot), валидация geo перед подменой, санитизация имени/портов, apt upgrade только при первичной установке, парсинг ключей под Xray 26.x, XHTTP packet-up
v3.6 Режим транспорта both (tcp+xhttp на одной ноде), авто-открытие xhttp-порта в UFW
v3.5 Аудит безопасности: лог 600, ключи не в лог, hub-IP убран, getent, backend=systemd, бэкапы конфигов
v3.4 Выбор транспорта tcp/xhttp; tcp использует flow Vision
v3.1 NODE_PORT в .env, geo до docker up, все read из /dev/tty
v3.0 XHTTP + steal_oneself, один домен, Xray на 443
v2.0 Полный хардинг, admin-user, fail2ban, sysctl
v1.0 Первая версия

Вклад

PR и issue приветствуются. Перед отправкой:

  • прогони ShellCheck: shellcheck deploy-remnanode.sh — должно быть без замечаний;
  • проверь синтаксис: bash -n deploy-remnanode.sh;
  • сохраняй идемпотентность и не пиши секреты в лог;
  • держи стиль: фазовые функции, хелперы ok/info/warn/die, set -euo pipefail.

Лицензия

MIT © anfixit

Благодарности

About

Скрипт для развёртывания и управления VPN-ноды на базе Remnawave панели + Xray-core

Resources

License

Security policy

Stars

4 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages