Перейти к содержимому

Вебхуки и reverse-proxy

ЮKassa, CryptoBot, Platega, Heleket и Tribute подтверждают оплату вебхуком — HTTP-запросом на ваш сервер (панель Remnawave шлёт свои события туда же). Внутри контейнера бот слушает порт 8080:

Путь Для чего
GET /healthz проверка «жив ли бот»
POST /webhook/yookassa уведомления ЮKassa
POST /webhook/cryptobot уведомления CryptoBot
POST /webhook/platega уведомления Platega
POST /webhook/heleket уведомления Heleket
POST /webhook/tribute уведомления Tribute
POST /webhook/remnawave события панели

Способ A (рекомендуется) — встроенный HTTPS прямо в боте. Бот сам получает TLS-сертификат Let’s Encrypt и слушает 80/443 — без отдельного nginx/Caddy. Шаги:

  1. Заведите домен/субдомен и направьте его A-записью на сервер бота (напр. bot.example.com → IP).
  2. В админке: Система → Вебхуки → 🌐 Публичный HTTPS (вкл) → 🔗 Домен (вписать домен) → 🚀 Применить. Бот сам пропишет порты 80/443 в docker-compose.yml и перезапустится; сертификат подтянется при первом запросе.
  3. Порты 80 и 443 на сервере должны быть свободны. Если их уже занял reverse-proxy панели (Caddy/nginx) — используйте способ B.

Способ B — за reverse-proxy панели. Бот отдаёт plain HTTP на 8080, HTTPS терминирует прокси панели: добавьте в Caddy/nginx проксирование /webhook/http://remnabot:8080. Либо опубликуйте порт (ports: ["8080:8080"]) и поставьте свой HTTPS-прокси.

⚠️ Если включены Mini App или веб-кабинет, одного location /webhook/ недостаточно — они живут на других путях того же порта: /miniapp/ + /api/miniapp/, путь кабинета (по умолчанию /cabinet/) + /api/cabinet/ + /flags/. Проще всего проксировать на бот весь домен целиком (location /) — готовый пример nginx ниже, в разделе про reverse-proxy. И обязательно передавайте заголовок X-Forwarded-Proto: https — по нему кабинет понимает, что TLS терминирован на прокси; без него он ответит «требуется HTTPS».

Затем в кабинете провайдера укажите URL вебхука (домен из способа A или ваш прокси):

  • ЮKassa: https://ВАШ_ДОМЕН/webhook/yookassa
  • CryptoBot: https://ВАШ_ДОМЕН/webhook/cryptobot
  • Platega: https://ВАШ_ДОМЕН/webhook/platega
  • Heleket: https://ВАШ_ДОМЕН/webhook/heleket
  • Tribute: https://ВАШ_ДОМЕН/webhook/tribute (тот же API-ключ, что в админке — по нему проверяется подпись)

Вебхук самой панели (не платёжки): в настройках Remnawave укажите https://ВАШ_ДОМЕН/webhook/remnawave, придумайте секрет и вбейте его же в боте (Система → Вебхуки → Секрет). По этим событиям бот шлёт пользователям напоминания «подписка скоро истечёт» и «подписка истекла», «трафик исчерпан», а с плагином torrent-blocker — обрабатывает отчёты о торрентах (для них секрет обязателен). Напоминания об истечении работают и на панелях 2.7.x (user.expires_in_*), и на 2.8.0+ / 3.x (user.expiration — включите на панели EXPIRATION_NOTIFICATIONS_ENABLED).

Даже если вебхук не дойдёт, фоновый реконсилятор перепроверит статус у провайдера и довыдаст подписку — деньги не потеряются. Но вебхук всё равно стоит настроить ради мгновенной выдачи.

Reverse-proxy и безопасность (рекомендации для прода)

Заголовок раздела «Reverse-proxy и безопасность (рекомендации для прода)»

Встроенный HTTPS (способ A) удобен для старта, но для продакшена — особенно если включены Mini App и веб-кабинет — рекомендуется поставить перед ботом reverse-proxy (Caddy / nginx) или Cloudflare и не выставлять Go-бинарь напрямую в интернет. Сам Go-сервер безопасен (таймауты, лимиты тела, rate-limit, security-заголовки уже есть в коде), вопрос в схеме развёртывания:

  • Wildcard-сертификат. Терминируйте TLS на прокси сертификатом *.ваш-домен, а бот держите на 127.0.0.1:8080 (без встроенного autocert). Индивидуальный сертификат на конкретный хост навсегда попадает в публичные Certificate Transparency логи (crt.sh / Censys) — по ним веб-кабинет элементарно находят. Wildcard это убирает.
  • Непривилегированный процесс. За прокси боту не нужны порты 80/443 и root/CAP_NET_BIND_SERVICE — запускайте под обычным пользователем.
  • Скрытый origin. Закройте фаервол (ufw/nftables): наружу только 80/443, остальное — deny. За Cloudflare разрешите origin принимать трафик только с диапазонов прокси — так реальный IP сервера не виден сканерам (Shodan / Censys).
  • Защита от перебора. fail2ban / CrowdSec на прокси против брутфорса логина и сканирования путей. У кабинета уже есть собственный rate-limit (15 запросов / 5 мин на эндпоинты авторизации).
  • Разделение доменов. Кабинет, панель Remnawave и страницу подписки держите на разных доменах/хостах, каждый со своим wildcard-сертом — перечисление одного не раскрывает остальные.
  • CAA-запись на ваш CA, чтобы сторонний центр сертификации не выпустил (и не засветил в CT) сертификат на ваш хост.

Минимальный рабочий пример nginx для кабинета (отдельный поддомен, бот на 127.0.0.1:8080):

server {
listen 443 ssl;
server_name cab.example.com; # домен кабинета
ssl_certificate /etc/ssl/wildcard.pem; # лучше wildcard *.example.com (см. выше)
ssl_certificate_key /etc/ssl/wildcard.key;
location / {
proxy_pass http://127.0.0.1:8080; # порт бота — тот же, что для вебхуков
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme; # обязательно: иначе кабинет ответит «требуется HTTPS»
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Проксируется весь location /, потому что на порту бота живут сразу все пути: вебхуки (/webhook/), Mini App (/miniapp/, /api/miniapp/), кабинет (путь из админки, по умолчанию /cabinet/, плюс /api/cabinet/ и /flags/). Если домен уже занят другим сервисом и location / отдать нельзя — проксируйте перечисленные пути отдельными location на тот же порт. Для входа в кабинет через Telegram укажите домен кабинета у @BotFather командой /setdomain.

Кабинет уже отдаёт noindex/robots, Referrer-Policy: no-referrer, HSTS, anti-fingerprint и хостит флаги локально — но это работает в полную силу только если хост не светится в CT-логах и у сканеров, поэтому wildcard-серт + скрытый origin для прод-кабинета критичны.