VPN Bot — продажа VPN подписок

Обзор

Telegram-бот для продажи и управления VPN подписками. Использует AmneziaWG + xray Reality.

Технологии

  • AmneziaWG — obfuscated WireGuard (обходит DPI/ТСПУ)
  • xray Reality — VLESS поверх TLS, маскируется под легитимный HTTPS
  • CF-front — Cloudflare fronting для VLESS (домен kolobas.top)
  • awgnode — кастомный installer/API для AmneziaWG нод

Архитектура нод (уточнено 2026-08-25 — важная поправка)

193.42.124.166 — НЕ клиентская VLESS-нода. Это панель/бэкенд (Remnawave backend + бот), на 443 висит nginx с server_name panel.smartplatforma.ru — обычная HTTPS-панель, никакого Reality-камуфляжа там нет и не должно быть. Раньше в этом файле она ошибочно значилась как “DE-нода” — это неверно, IP из coreclaw/.env (VPN_NODES) — просто имя для health-check, не архитектурная роль.

Реальные клиентские узлы, отдающие VLESS/Reality-трафик:

РегионIPПровайдерСтатус
DE (Германия)132.243.224.242 (de-hostkey)HostKey🟢 жив, Reality-камуфляж исправен (проверено 2026-08-25)
NL (Нидерланды)138.124.119.57Aeza🟢 жив, Reality-камуфляж исправен (проверено 2026-08-25)

193.42.124.166 (панель/бэкенд/бот) — Beget (RU-хостинг физически, см. servers) — 🟢 жив (восстановился сам, см. инцидент id:52 ниже).

Сторонний no-panel installer (2server-privacy.vercel.app) — разобран 2026-08-25

Сергей скинул ссылку на гайд блогера (Dmitriymarketing): установка личного VPN одной командой (bash -c "$(curl -fsSL https://2server-privacy.vercel.app/install.sh)" / PowerShell-аналог) на два своих VPS (зарубеж+RU), без панели типа Remnawave. Архитектура та же, что у нас: VLESS+WS+TLS через nginx-релей, сайт-прикрытие, Let’s Encrypt.

Скачал и раскодировал (клиентский install.sh + два вшитых в base64 серверных скрипта install_vpn.sh/install_entry.sh) — проверка на бэкдоры/эксфильтрацию чистая:

  • Внешние curl только к api.ipify.org (узнать свой IP) и официальному XTLS/Xray-install с GitHub
  • UUID — /proc/sys/kernel/random/uuid (реально случайный, не захардкожен)
  • Нет добавления authorized_keys/пользователей/sudo, нет обратной связи к домену автора
  • Firewall — только 22/80/443

Вывод: скрипт легитимный, делает то, что заявлено. Не используется в проде (отдельная штука, просто попросили проверить) — держим как референс на случай, если Сергей решит опробовать/сравнить с текущей Remnawave-схемой.

Конфигурация xray Reality (рабочая)

{
  "fingerprint": "safari",
  "serverName": "www.googletagmanager.com"
}
  • fp=safari пробивает ТСПУ (chrome палится в xray 25.9.11)
  • GTM SNI работает лучше cloudflare.com (ТСПУ режет cloudflare.com SNI)
  • BBR включён

CF-front (kolobas.top)

  • Статус: 🟢 все 4 ноды работают
  • VLESS внутри TLS (без CF-front ТСПУ режет на некоторых ISP, напр. Proxima)
  • iPhone + ISP Сергея: ТСПУ режет VLESS без CF, с CF всё работает

Reality-камуфляж на реальных нодах — исправен (перепроверено 2026-08-25)

Первая диагностика (2026-08-25 утро) была ошибочной — TLS-проба ушла не на тот сервер. Изначально проверялся 193.42.124.166, приняв его за “DE-ноду” по имени в [[projects/coreclaw]]/.env — но это панель/бэкенд, там на 443 честно висит nginx с реальным сертификатом panel.smartplatforma.ru, это не баг, а норма для этого хоста (см. архитектуру выше). Вывод “камуфляж сломан” был снят.

Перепроверено против правильных IP (openssl s_client -connect IP:443 -servername www.googletagmanager.com, сравнение с эталоном):

  • 132.243.224.242 (DE, реальная нода) — сертификат CN=*.google-analytics.com, Google Trust Services WE2, идентичен прямому запросу к настоящему www.googletagmanager.com. Камуфляж исправен.
  • 138.124.119.57 (NL) — тот же сертификат, тоже идентичен эталону. Камуфляж исправен.
  • Открытые порты на обеих: 22 (SSH), 443 (Reality), 8443 (вероятно CF-front origin). 2096/2097 закрыты — это порты личной ноды (xray-personal), не относятся к боту.

Вывод: TLS-камуфляж и fingerprint ни при чём. Дополнительно проверено через Remnawave API (25.08): fp=safari уже стоит на всех host-профилях (и на прямом Reality, и на wscf/CF) — не chrome. Значит блокировка не про SNI-сертификат и не про uTLS-fingerprint.

Реальная причина — перепроверена измерением 25.08 (не просто повтор старой записи от 14.08 — та была verbal-выводом без свежих цифр). check-host.net TCP-проверка (check-tcp, порт 443) с 11 мировых точек + Москва (ru1.node, AS14576):

Точка132.243.224.242:443138.124.119.57:443
Австрия/Испания/Франция/Индонезия/Индия/Иран/Молдова/Нидерланды/Польша/Словения/Вьетнам✅ 10-500мс✅ 15-20мс
Москва (ru1)❌ Connection timed out❌ Connection timed out
Москва → 1.1.1.1:443 (контроль, та же нода)✅ 19мс
Москва → 132.243.224.242:22 (SSH)❌ Connection timed out

Контроль подтверждает рабочую точку проверки. Блокируется весь IP на всех портах (не только 443/VLESS), TCP SYN не доходит вообще — значит не DPI-детект Reality-хендшейка, а IP-level блэкхол на маршруте до хоста, специфичный для России. Оба хостера (HostKey DE, Aeza NL) — дешёвые VPS-диапазоны, типичная цель блокировки. Рабочий профиль в Happ — wscf (через CloudFlare, другой видимый IP), не прямой Reality.

Мелкий хвост в конфиге inbound Germaniya-reality (не влияет, но стоит подчистить): в realitySettings одновременно dest: www.googletagmanager.com:443 и легаси-поле target: www.vk.com:443 — остаток от более старой настройки под vk.com, реально используется dest (TLS-проба это подтверждает).

Урок процесса: этот же вопрос уже был закрыт 14.08.2026 в servers (секция “de-hostkey”), а 25.08 расследование пошло заново с нуля (TLS-проба на неверный IP, потом SSH, разбор Reality-конфига) — потому что перед стартом не перечитал существующие записи про эту ноду. См. feedback_scope_and_reread_vault.

Инциденты

ДатаЧтоПричинаДлительность
2026-07-02 08:15–09:33Панель remnawave недоступнаBeget не поднял VPS после тех.обслуживания, помог техподдержка78 мин
2026-06-29 – 2026-07-02NL-нода (138.124.119.57) health-check таймаутыНода не была оплачена, оплачена 2026-07-023+ дня
2026-08-24 → 2026-08-25 (закрыт, id:52)DE-нода (193.42.124.166) не отвечалаНе диагностировано (причина неизвестна — не трогал прод без разрешения). Восстановилась сама между 2026-08-24 20:xx и 2026-08-25 08:xx: ping 0% loss, TCP:443 открыт~12-16 часов

Известные проблемы

ПроблемаСтатус
IPv6-only пользователи (МТС/Yota) не могут подключиться🔴 Открыта
MTProto ТСПУ блокирует JA3/JA4🔴 Открыта, ждём обновление Telegram
PSK bug в kobalt695/awgnode:0.1.1✅ Исправлен воркэраундом

Известные баги (закрыты)

PSK игнорируется при create_peer (awgnode 0.1.1, найден 2026-06-04): в /app/app/main.py create_peer() принимал req.preshared_key, но не передавал его в _awg_add_peer() — PSK попадал в клиентский .conf, но на сервере peer был без PSK → бесконечное «ожидание рукопожатия». Диагностика: docker exec awgnode awg show awg0 dump — во второй колонке peer’а должен быть PSK (base64), не (none). Исправлено в 0.1.2.

Наш awgnode палился ТСПУ из-за obfuscation params (закрыто 2026-06-02, commit 064f5b0): генератор ставил слишком большие Jmax/S2 (Jmax=1000 вместо 50, S2=661 вместо 98 у эталонного AmneziaVPN-installer) → response-пакет сервера ~750 байт вместо ~150-250 байт у AmneziaVPN → ТСПУ резал как аномальный handshake. Подкручены диапазоны (Jmax 40-80, S2 50-120, H1-H4 в 3e8…2e9) под AmneziaVPN-style. Урок: obfuscation-параметры WireGuard должны быть в диапазонах, неотличимых от эталонного клиента, а не рандомные на полный диапазон типа.

Reality: fingerprint safari против ТСПУ (2026-06-04) — дополнение к конфигу выше:

  • Причина, почему chrome палится: ТСПУ обучен на chrome+xray-latest (~90% VPN-трафика); наш xray 25.9.11 обновляет chrome uTLS-fingerprint до самого свежего Chrome, DPI палит как «новейший xray». safari uTLS обновляется редко, выглядит как обычный iOS-юзер.
  • Если safari тоже когда-нибудь заблокируют — пробовать по порядку: firefoxiosrandomized (рандомный JA3 каждый коннект) → откат версии xray-core (нужен кастомный image Remnawave node).
  • BBR sysctl на ноде (/etc/sysctl.d/99-xray-optimize.conf, применяется автоматически через _apply_bbr_sysctl() при установке ноды):
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
  • SNI сменён с www.cloudflare.com на www.googletagmanager.com в тот же заход — CF-домены в шорт-листе ТСПУ как VPN-маркер, GTM ходит со всех сайтов мира, не блокируется.
  • Источники идей, проверенных в сессии 2026-06-04: just-russian-amateur/docker-for-xray-reality (vk.com dest), 0xevn/xray-reality-setup (BBR sysctl, shortIds массив).

Латвийская AWG-нода (эталон, личная нода Сергея): отдельный self-hosted AmneziaWG-сервер 91.218.142.173:34900, поставлен через официальный AmneziaVPN-installer, не часть vpnbot. Обфускация с маленьким Jmax=50 — используется как ориентир при отладке клиентских конфигов (см. таблицу Jmax/S2 выше).

AWG — архитектура и уроки эксплуатации

Биллинг: без тарифов/планов — ежедневное списание cost_per_day за факт активной подписки. AWG не тарифицируется отдельно, это часть той же подписки (UserConfig). Freeze при исчерпании баланса (5 дней) → удаление.

Unified installer (архитектурное решение): AWG-нода ставится единым flow вместе с Remnawave-нодой через NodeInstallerService.install_node() — один UI-вход в админке поднимает на VPS обе ноды последовательно. Причина: «не плодить инфраструктуру по сайтам» — раньше был отдельный FSM для установки AWG, унифицировано в один flow.

UDP-хостинг — не у всех провайдеров работает: подтверждённая матрица (2026-05-28/29) —

  • Aeza (138.124.119.57) — UDP полностью открыт, AWG работает.
  • HostKey/Datapacket-NL (194.41.113.12) — провайдер режет UDP целиком (ни 57157, ни 443 не доходят), только TCP/VLESS-Reality работает там.
  • Вывод: перед установкой AWG-ноды на новом хостере — сначала тест UDP, иначе фича молча не работает у пользователей.

Obfuscation randomization обязателен: дефолтные H1-H4 = 1,2,3,4 (стандартный WireGuard) палятся ТСПУ мгновенно — install.sh/installer генерит случайные 32-bit magic headers на каждую ноду, сохраняет в /opt/awgnode/data/obfuscation.json.

CF-front self-signed cert: origin-сертификат — self-signed P-256 ECDSA, 10 лет, inline в конфиге профиля Remnawave. CF SSL/TLS режим обязательно Full (не Strict — CF не должен строго проверять self-signed origin cert). Порт origin — 8443 (443 занят Reality).

⚠️ dev/prod на одном CF-аккаунте — источник инцидента: при тесте один раз dev-бот случайно перезаписал прод-CF-запись cf-de.kolobas.top (с прод-IP на dev/Aeza-IP), сломав прод-Германию у юзеров — потому что dev и prod исторически использовали один и тот же CF-аккаунт/зону kolobas.top. Если заводится новый dev-контур — держать на отдельном CF-аккаунте или отдельном домене.

Repo

  • kobalt695/awgnode — installer/API для AmneziaWG нод
  • kobalt695/vpnbot — основной бот (на prod-сервере 193.42.124.166)

Интеграция с платежами

  • Подписки в Google Sheets (нужно заполнить server + paid_until)
  • Telegram alerts за 7 и 1 день до истечения — TODO