Чинит .env.example: убирает мёртвый ADMIN_TG_ID, добавляет PROXY_INTERNAL_SECRET

ADMIN_TG_ID нигде не читается с тех пор, как admin_guard заменили на ролевую
систему (owner/staff/node_manage/partner_guard) — оставлять его в примерах
вводит в заблуждение. PROXY_INTERNAL_SECRET, наоборот, обязателен (main.rs
падает без него при старте), но отсутствовал во всех трёх .env*.example.

Заодно поправлен src/modules/auth/README.md — описывал admin_guard,
которого больше не существует.
This commit is contained in:
2026-07-09 15:33:33 +07:00
parent e6c81bf8fd
commit 591643d364
4 changed files with 50 additions and 19 deletions
+5 -1
View File
@@ -28,7 +28,11 @@ CF_API_TOKEN=CHANGE_ME_CLOUDFLARE_DNS_EDIT_TOKEN
JWT_SECRET=CHANGE_ME_DEV_JWT_SECRET JWT_SECRET=CHANGE_ME_DEV_JWT_SECRET
ARGON_SALT=CHANGE_ME_DEV_ARGON_SALT_MIN_16_CHARS ARGON_SALT=CHANGE_ME_DEV_ARGON_SALT_MIN_16_CHARS
TON_MASTER_WALLET=UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKK8y TON_MASTER_WALLET=UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKK8y
ADMIN_TG_ID=0
# Общий секрет с прокси-нодами этого dev-стенда (--require-auth) — обязателен,
# без него бэкенд не стартует. То же значение должно быть в .env.example
# netrunner-proxy на самих нодах.
PROXY_INTERNAL_SECRET=CHANGE_ME_DEV_PROXY_INTERNAL_SECRET
# Опционально: без него оплата через @CryptoBot просто вернёт "provider not # Опционально: без него оплата через @CryptoBot просто вернёт "provider not
# supported", остальное продолжает работать как раньше. Токен берётся у # supported", остальное продолжает работать как раньше. Токен берётся у
+4 -1
View File
@@ -21,9 +21,12 @@ RUST_LOG=netrunner_control_plane=debug,axum=info,tower_http=debug,sqlx=warn
JWT_SECRET=dev_jwt_secret_change_me JWT_SECRET=dev_jwt_secret_change_me
ARGON_SALT=dev_stealth_salt_minimum_16_chars ARGON_SALT=dev_stealth_salt_minimum_16_chars
TON_MASTER_WALLET=UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKK8y TON_MASTER_WALLET=UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKK8y
ADMIN_TG_ID=0
TELOXIDE_TOKEN=123456789:YOUR_DEV_BOT_TOKEN_HERE TELOXIDE_TOKEN=123456789:YOUR_DEV_BOT_TOKEN_HERE
# Общий секрет с локальным прокси (--require-auth, см. .env.example
# netrunner-proxy) — обязателен, без него бэкенд не стартует.
PROXY_INTERNAL_SECRET=dev_stealth_salt_minimum_16_chars_proxy
# Опционально: без него оплата через @CryptoBot вернёт "provider not # Опционально: без него оплата через @CryptoBot вернёт "provider not
# supported", остальное работает как обычно. Токен — у @CryptoBot: /pay -> # supported", остальное работает как обычно. Токен — у @CryptoBot: /pay ->
# Create App -> Payment Token. # Create App -> Payment Token.
+35 -14
View File
@@ -1,17 +1,22 @@
# ===================================================================== # =====================================================================
# === DATABASE CONFIGURATION === # === DATABASE CONFIGURATION ===
# ===================================================================== # =====================================================================
# ВАЖНО: значения ниже — это плейсхолдеры-заглушки (CHANGE_ME_*), не реальный
# пароль. Не копировать "как есть" — реальный пароль генерировать самостоятельно
# (например `openssl rand -base64 24`) и никогда не коммитить .env с настоящим
# значением (см. .gitignore — .env/.env.* уже исключены).
#
# ДЛЯ ЛОКАЛЬНЫХ ТЕСТОВ НА ТВОЕМ ПК: # ДЛЯ ЛОКАЛЬНЫХ ТЕСТОВ НА ТВОЕМ ПК:
# DATABASE_URL=postgres://netrunner_admin:dev_root_123@77.110.106.113:5432/netrunner # DATABASE_URL=postgres://netrunner_admin:CHANGE_ME_DB_PASSWORD@<ip-впс>:5432/netrunner
# #
# ДЛЯ ЗАПУСКА НА САМОЙ ВПС (Через Docker Compose): # ДЛЯ ЗАПУСКА НА САМОЙ ВПС (Через Docker Compose):
# DATABASE_URL=postgres://netrunner_admin:dev_root_123@db:5432/netrunner # DATABASE_URL=postgres://netrunner_admin:CHANGE_ME_DB_PASSWORD@db:5432/netrunner
DATABASE_URL=postgres://netrunner_admin:dev_root_123@77.110.106.113:5432/netrunner DATABASE_URL=postgres://netrunner_admin:CHANGE_ME_DB_PASSWORD@db:5432/netrunner
DB_USER=netrunner_admin DB_USER=netrunner_admin
DB_NAME=netrunner DB_NAME=netrunner
DB_PASSWORD=dev_root_123 DB_PASSWORD=CHANGE_ME_DB_PASSWORD
# Кеш курса TON (не источник истины — если недоступен, приложение просто # Кеш курса TON (не источник истины — если недоступен, приложение просто
# ходит в TonAPI напрямую на каждый инвойс, как раньше). # ходит в TonAPI напрямую на каждый инвойс, как раньше).
@@ -20,11 +25,24 @@ REDIS_URL=redis://redis:6379
# ===================================================================== # =====================================================================
# === SECRETS & CRYPTO SECURITY === # === SECRETS & CRYPTO SECURITY ===
# ===================================================================== # =====================================================================
JWT_SECRET=YOUR_RANDOM_SECRET_KEY_CHANGE_ME_IN_PRODUCTION JWT_SECRET=CHANGE_ME_JWT_SECRET_openssl_rand_hex_32
ARGON_SALT=какая-то-рандомная-длинная-строка-минимум-16-символов ARGON_SALT=CHANGE_ME_ARGON_SALT_MIN_16_CHARS
GRAFANA_PASSWORD=netrunner_admin_2026 GRAFANA_PASSWORD=CHANGE_ME_GRAFANA_PASSWORD
TON_MASTER_WALLET=UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKK8y TON_MASTER_WALLET=UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKK8y
# =====================================================================
# === БЭКАПЫ POSTGRES (см. scripts/backup.sh, сервис `backup` в
# === docker-compose.prod.yml) ===
# =====================================================================
# Без RCLONE_REMOTE/RCLONE_CONFIG_CONTENT бэкапы всё равно снимаются каждые
# BACKUP_INTERVAL_SEC (по умолчанию 6ч) и хранятся локально в volume
# netrunner_db_backups — но только на этом же VPS. Для реальной защиты от
# падения диска/потери сервера нужна офсайт-копия:
# BACKUP_INTERVAL_SEC=21600
# BACKUP_RETENTION_DAYS=14
# RCLONE_REMOTE=b2:netrunner-backups
# RCLONE_CONFIG_CONTENT содержимое rclone.conf одной переменной, см. rclone.conf.example
# Опционально: без него оплата через @CryptoBot вернёт "provider not # Опционально: без него оплата через @CryptoBot вернёт "provider not
# supported", остальные провайдеры продолжают работать. Токен — у @CryptoBot: # supported", остальные провайдеры продолжают работать. Токен — у @CryptoBot:
# /pay -> Create App -> Payment Token. # /pay -> Create App -> Payment Token.
@@ -39,6 +57,15 @@ TELOXIDE_TOKEN=123456789:YOUR_REAL_TELEGRAM_BOT_TOKEN_HERE
BOT_USERNAME=ntrnr_vpn_bot BOT_USERNAME=ntrnr_vpn_bot
WEB_APP_BASE_URL=https://account.netrunner-vpn.com WEB_APP_BASE_URL=https://account.netrunner-vpn.com
# =====================================================================
# === ВНУТРЕННИЙ КОНТРАКТ С ПРОКСИ-НОДАМИ (обязателен, без него старт падает) ===
# =====================================================================
# Общий секрет между бэкендом и КАЖДОЙ прокси-нодой (X-Internal-Secret на
# POST /internal/validate и /internal/usage, см. modules::proxy_internal) —
# то же самое значение прописывается на нодах при провижининге
# (NodeService::provision_node_via_ssh) и в .env.example netrunner-proxy.
PROXY_INTERNAL_SECRET=CHANGE_ME_PROXY_INTERNAL_SECRET_openssl_rand_hex_32
# ===================================================================== # =====================================================================
# === APPLICATION RUNTIME SETTINGS === # === APPLICATION RUNTIME SETTINGS ===
# ===================================================================== # =====================================================================
@@ -75,10 +102,4 @@ VPS_IP=77.110.106.113
DEPLOY_DIR=/root/netrunner-core DEPLOY_DIR=/root/netrunner-core
BINARY_NAME=netrunner-control-plane BINARY_NAME=netrunner-control-plane
# Образ, который тянет прод-стек (docker-compose.prod.yml). # Образ, который тянет прод-стек (docker-compose.prod.yml).
IMAGE=ghcr.io/nineap/netrunner-control-plane:latest IMAGE=ghcr.io/nineap/netrunner-control-plane:latest
# =====================================================================
# === ADMIN ===
# =====================================================================
ADMIN_TG_ID=00000
+6 -3
View File
@@ -47,9 +47,12 @@
cookie**, дополнительно проверяет `Origin`/`Referer` против `CSRF_ALLOWED_ORIGINS` — это cookie**, дополнительно проверяет `Origin`/`Referer` против `CSRF_ALLOWED_ORIGINS` — это
CSRF-защита. Bearer-запросы её не проходят и не должны: подделать `Authorization`-заголовок CSRF-защита. Bearer-запросы её не проходят и не должны: подделать `Authorization`-заголовок
с чужого origin браузер не даст, поэтому CSRF для них неактуален. с чужого origin браузер не даст, поэтому CSRF для них неактуален.
- `admin_guard` — должен идти **после** `auth_guard` в цепочке слоёв (читает юзера из - `owner_guard` / `staff_guard` / `node_manage_guard` / `partner_guard` — ролевые гварды
extensions). Пропускает, если `tg_id` юзера совпадает с `ADMIN_TG_ID` из `.env` или его админки (Owner/Moderator/Partner), должны идти **после** `auth_guard` в цепочке слоёв
`role == "admin"`. (читают роль юзера из extensions, второй запрос к БД не нужен). Без завязки на Telegram —
роль назначается через `staff`-модуль (создание Owner — CLI `--create-owner`, дальше
Owner/Moderator создают друг друга через API). `node_manage_guard` — Owner всегда, либо
Moderator с выданным правом `can_manage_nodes`.
## Sybil-защита ## Sybil-защита