Безопасность
Безопасность Minishop в первую очередь держится на стабильных секретах, корректном разделении публичных доменов и ограниченном доступе к админке.
Секреты
Заголовок раздела «Секреты»WEBAPP_SESSION_SECRETдолжен быть постоянным между рестартами, иначе Web App-сессии станут невалидными.WEBHOOK_SECRET_TOKENзащищает вебхук Telegram.PANEL_WEBHOOK_SECRETпроверяет входящие события Remnawave Panel. Секрет задается в Remnawave Panel и вставляется в настройки бота.- Платежные токены и webhook-секреты храните в
.envили настройках админки с учетом доступа к серверу.
Сгенерировать секрет можно так:
Telegram антифлуд
Заголовок раздела «Telegram антифлуд»Апдейты Telegram-бота проходят через ранний anti-flood middleware до sync профиля, проверки каналов и логирования действий, которые обращаются к базе. Профиль по умолчанию специально мягкий: он не должен мешать быстрым обычным нажатиям кнопок, но отбрасывает экстремальные всплески сообщений и callback от одного источника до того, как они разгонят записи в БД, платежные обработчики или Telegram FloodWait.
Настройки доступны в Админка -> Система -> Настройки -> Система -> Telegram
антифлуд. Для обычного приватного продающего бота дефолтов достаточно, поэтому
они не добавлены в .env.example. Меняйте их только если реальный трафик
показывает, что пороги нужно расширить или сузить.
TELEGRAM_DROP_NON_PRIVATE_UPDATES=Trueотбрасывает апдейты из групп и каналов до дорогих middleware. Оставляйте включенным, если бот не должен работать вне приватных чатов.TELEGRAM_ANTIFLOOD_ENABLED=Trueвключает per-user/per-chat лимиты. Значение0у отдельного числового лимита отключает только этот лимит.TELEGRAM_ANTIFLOOD_WINDOW_SECONDS=60задает общее скользящее окно. Дефолты рассчитаны на нормальные button-heavy флоу:180всех апдейтов,120сообщений,240callback,60inline-запросов,30команд/startи60тяжелых callback за окно.TELEGRAM_ACTION_COOLDOWN_ENABLED=Trueдедуплицирует точные повторные платежные и trial callback от того же пользователя. Разные платежные payload не объединяются, поэтому обычный checkout остается независимым.
Доступ администраторов
Заголовок раздела «Доступ администраторов»- Доступ к админке задают роли
ownerиadmin, сохранённые у внутреннего аккаунта. - Первый владелец получает роль при входе по заранее заданным
BOOTSTRAP_OWNER_TELEGRAM_IDилиBOOTSTRAP_OWNER_EMAIL; email должен быть подтверждён. Оба поля необязательны, назначается только один аккаунт. Сохранённое назначение владельца, даже отозванное, блокирует повторную автоматическую выдачу. - Без этих полей зарегистрируйте аккаунт и выполните серверную команду
docker compose exec backend python backend/scripts/bootstrap_owner.py --minishop-id ms_<id>. Привязка Telegram/email для этой команды не требуется. Подробности: первый владелец. ADMIN_IDSслужит только источником одноразового импорта старых администраторов при достоверной привязке Telegram identity.
Публичные URL
Заголовок раздела «Публичные URL»WEBHOOK_BASE_URLдолжен вести на backend-сервер вебхуков.- В Remnawave Panel
WEBHOOK_URLдолжен бытьWEBHOOK_BASE_URL+/webhook/panel, напримерhttps://app.example.com/webhook/panel. SUBSCRIPTION_MINI_APP_URLдолжен вести на frontend/Mini App-домен.- Не добавляйте
/api,/authили webhook-пути вSUBSCRIPTION_MINI_APP_URL.
Раздельное размещение frontend и backend
Заголовок раздела «Раздельное размещение frontend и backend»- Браузер пользователя должен ходить только на frontend origin:
https://app.example.com/api/.... WEBAPP_API_BASE_URLоставляйте/api; отдельный backend origin в frontend JS не является защитой и делает WebApp API напрямую видимым пользователю.- Для protected upstream используйте
WEBAPP_BACKEND_UPSTREAMу frontend nginx иMINISHOP_EDGE_TOKEN, который nginx добавляет к upstream-запросам server-side. MINISHOP_EDGE_TOKENнельзя отдавать в runtime config или frontend bundle: browser-visible token виден в DevTools.- Token/firewall/VPN применяются к WebApp API plane
backend:8081. Telegram, payment provider и Remnawave Panel webhook остаются на public webhook planebackend:8080и не должны требоватьMINISHOP_EDGE_TOKEN. - При upstream
https://bot.example.comнастройте Host/SNI (WEBAPP_BACKEND_UPSTREAM_HOST=bot.example.com) и route order так, чтобы/api/*,/auth/*,/open-app, logo/theme/favicon paths попадали в8081раньше generic webhook fallback.
IP allowlist вебхуков
Заголовок раздела «IP allowlist вебхуков»- Reverse proxy для
WEBHOOK_BASE_URLдолжен передаватьX-Forwarded-Forс реальным IP отправителя. TRUSTED_PROXIESдолжен включать IP/CIDR последнего proxy-hop до backend. Иначе платежные webhook-обработчики будут проверять allowlist по IP proxy или Docker gateway.- Для домена за Cloudflare backend принимает
CF-Connecting-IP, только если ближайший недоверенный hop входит в официальные сети Cloudflare. Добавлять эти публичные CIDR вTRUSTED_PROXIESне требуется. - Если
TRUSTED_PROXIESне задан, приложение, Compose-профили и установщик доверяют loopback и стандартным сервисамfrontend,caddy,nginx,angie,newt,newt-2. Именаhost:разрешаются только в отдельные IP, обновляются раз в минуту и игнорируются, пока сервис отсутствует. Это поддерживает несколько прокси и пересоздание контейнеров без ручного изменения адресов. - Для собственного proxy добавьте его точный IP/CIDR или
host:имя-сервисак стандартному списку ниже. Установщик добавляет имя выбранного контейнера автоматически; при host-network добавляет точный gateway Docker-сети приложения. Явные настройки оператора сохраняются. При обновлении замените старое доверие всем частным сетям в.env. - Если вы сознательно хотите доверять любому proxy-hop, используйте
0.0.0.0/0,::/0, но только когда backend не опубликован напрямую, а внешний proxy очищает входящийX-Forwarded-For.
Для стандартной установки оставьте переменную незаданной. Если нужен дополнительный proxy:
Список доверенных входящих прокси не разрешает исходящие подключения во внутреннюю сеть. Публичные SMTP, платёжные API и сервисы мониторинга продолжают работать с обычными настройками; внутренние адреса и собственные API-шлюзы разрешаются настройками администратора, как описано ниже.
Дополнительно
Заголовок раздела «Дополнительно»Исходящие запросы Xray Checker и Uptime Kuma проверяют реальные DNS-адреса и перенаправления.
Внутренний сервер мониторинга разрешён по точному имени и порту текущего URL,
заданного оператором в .env или сохранённого в админке. Настройкам администратора
доверяем по умолчанию: сохранение, замена и сброс URL сразу обновляют разрешения и
соединения без перезапуска backend. Старые запросы завершаются с прежними настройками,
а новые используют текущий адрес; прежние хосты и порты не остаются разрешёнными.
Link-local адреса, включая адреса metadata, не разрешаются.
SMTP также проверяет DNS и подключается к проверенному IP с TLS-проверкой исходного
имени. Внутренний SMTP разрешён по текущим явно заданным SMTP_HOST, SMTP_PORT и
SMTP_FALLBACK_PORTS из .env или админки. Изменения применяются к следующему
подключению без перезапуска; удалённые хосты и порты перестают быть разрешёнными.
URL курсов PayKilla принимает только HTTP(S); синхронный и асинхронный пути ограничивают
размер ответа, проверяют DNS и каждое перенаправление. Внутренний сервис курсов можно
задать через PAYKILLA_EXCHANGE_RATE_URL в .env или админке. Оба пути используют
текущий адрес, а смена URL обновляет разрешения и выбор кэша курса без перезапуска.
Платёжные API отправляют ключи только на текущий адрес <PROVIDER>_BASE_URL, включая
его схему и порт. Адрес можно задать в .env или сохранить в админке; сохранённые ранее
настройки также учитываются. Изменение в админке применяется без перезапуска, а уже
начатые запросы завершаются с прежними настройками. Явно настроенный API-шлюз может
использовать частный IP или внутреннее имя. HTTP(S)-адрес проверяется перед сохранением,
DNS — при подключении; служебные адреса, включая metadata, запрещены. Перенаправление
на другой origin не пересылает ключи, даже если это штатный адрес провайдера.
Отдельный worker обновляет SMTP и настройки платёжных провайдеров из базы каждые
5 секунд, включая сброс к значениям .env. Перезапуск worker для смены адреса
не требуется; настройки в процессе backend применяются сразу после сохранения.
Файлы инструкций доступны внутри data/subpage-config или по исходному пути из .env.
Чтение ограничено 4 MiB и обычными файлами; административная смена пути не даёт доступ
к произвольным файлам сервера.
- Используйте HTTPS на всех публичных доменах.
- Ограничивайте доступ к серверу и
.env. - Следите за логами платежных вебхуков и вебхуков панели.
- После ротации секретов перезапускайте соответствующие сервисы и проверяйте вебхуки.
См. также переменные окружения и развертывание.