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.57 | Aeza | 🟢 жив, 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:443 | 138.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-02 | NL-нода (138.124.119.57) health-check таймауты | Нода не была оплачена, оплачена 2026-07-02 | 3+ дня |
| 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».safariuTLS обновляется редко, выглядит как обычный iOS-юзер. - Если safari тоже когда-нибудь заблокируют — пробовать по порядку:
firefox→ios→randomized(рандомный 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