VPN·HUB·CRACK
Один хост → тысячи юзеров: масштабирование · VPN HUB CRACK
Один хост → тысячи юзеров: масштабирование
Хосты: масштабирование
Два независимых приёма масштабирования: 1. Один хост → несколько нод: раздаём нагрузку по числу пользователей. 2. Одна нода → несколько транспортов (способы упаковки трафика: TCP/gRPC/xHTTP): переживаем разные типы DPI.
📖 Незнакомые слова? Все термины простыми словами смотрите в Словаре терминов.
1. Один хост → несколько нод (распределение по юзерам)
Проблема: у хоста один Address, а нод нужно несколько. Решение: поставить перед нодами L4-балансировщик (HAProxy/nginx распределяют клиентов по нодам) с методом least-conn (раздаёт по числу активных соединений ≈ по пользователям). Все ноды крутят один и тот же inbound с одинаковыми ключами Reality, чтобы любая нода обслужила любого клиента.
Шаги
- В Remnawave: один Config Profile (полный Xray-конфиг ноды), в нём один inbound (VLESS Reality). Включите этот inbound на всех нодах N1/N2/N3. Ключ Reality лежит в профиле → у всех нод идентичный → клиент валиден на любой.
- Поднимите фронт-балансер (отдельный дешёвый VPS или одна из нод) на :443, бэкенды: IP нод на их рабочем порту (например 8443, чтобы не конфликтовать с фронтом).
- Host в панели:
Address= домен/IP балансировщика, Inbound = тот самый. Клиент идёт на балансер, тот раздаёт по least-conn.
HAProxy (least-conn, TLS-passthrough, Reality цел)
frontend ft
bind 0.0.0.0:443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
default_backend pool
backend pool
mode tcp
balance leastconn # раздаём по числу активных соединений ≈ по юзерам
option ssl-hello-chk
server n1 10.0.0.11:8443 check
server n2 10.0.0.12:8443 check
server n3 10.0.0.13:8443 check
# server n4 10.0.0.14:8443 check backup # горячий резерв (только при падении основных)
Слить ноду без обрыва (рантайм-API):
echo "set server pool/n2 state drain" | socat stdio /var/run/haproxy.sock
nginx stream (альтернатива)
stream {
upstream pool { least_conn;
server 10.0.0.11:8443 max_fails=2 fail_timeout=10s;
server 10.0.0.12:8443 max_fails=2 fail_timeout=10s;
server 10.0.0.13:8443; }
server { listen 443; proxy_pass pool; proxy_connect_timeout 3s; }
}
⚠️ Reality-ключ один на все ноды за балансером, иначе клиент, попавший на «другую» ноду, не подключится. Для длинных VPN-сессий least-conn лучше round-robin (RR перегрузит того, кому достались долгие сессии). Это только TCP. Hysteria2 (протокол поверх QUIC/UDP) балансируйте отдельно (DNS/порт-хоппинг).
Альтернатива без фронта: сквад-сплит
Статически делите пользователей по сквадам, каждый сквад → свой одно-нодовый хост. Грубее, но без инфраструктуры балансера. Подходит, когда ноды разной ёмкости (премиум-юзеров на мощные).
2. Одна нода → несколько транспортов (TCP / gRPC / xHTTP)
Разные транспорты режут по-разному. Держите на одной ноде три инбаунда (все Reality, на разных портах) и отдайте их тремя хостами: клиент получит 3 сервера (TCP/gRPC/xHTTP), рабочий выберется сам.
Сгенерируйте ключи (один комплект Reality можно переиспользовать на ноде, shortId разные):
xray x25519 # privateKey → сервер, publicKey → клиент
xray uuid # id пользователя
openssl rand -hex 8 # shortId (свой на каждый инбаунд)
🔑 Ключи Reality проще всего сгенерировать прямо в панели. В редакторе конфига Remnawave (кнопка меню рядом с «Форматировать») есть пункт «Сгенерировать ключи» — он сам подставит пару
privateKey/publicKey, ничего ставить и вызывать вручную не нужно. Там же есть «Скачать с Github» — подтянуть свежее ядро Xray.Если нужно получить пару вне панели (например, готовите конфиг заранее), подойдёт любой путь: - на ноде, внутри контейнера:
docker exec remnanode xray x25519; - на любой машине, хоть на своём ноутбуке — ключи к серверу не привязаны:wget -qO- https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-64.zip | busybox unzip - xray && chmod +x xray && ./xray x25519
privateKeyидёт в конфиг ноды,publicKey— на Host в панели.
Конфиг-профиль ноды (3 транспорта в одном, вставляется целиком)
Один Config Profile с тремя инбаундами (TCP / gRPC / xHTTP): общий privateKey, разные порты и shortId. Поменяйте только target/serverNames (донор) и privateKey:
{
"log": { "loglevel": "none" },
"inbounds": [
{
"tag": "vless-tcp",
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": { "clients": [], "decryption": "none" },
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"show": false,
"target": "www.cloudflare.com:443", // ← донор (одинаковый на всех трёх)
"serverNames": ["www.cloudflare.com"],
"privateKey": "PRIVATE_KEY_X25519", // ← один privateKey на ноду (общий для 3 инбаундов)
"shortIds": ["a1b2c3d4"]
}
}
},
{
"tag": "vless-grpc",
"listen": "0.0.0.0",
"port": 8443,
"protocol": "vless",
"settings": { "clients": [], "decryption": "none" },
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
"streamSettings": {
"network": "grpc",
"security": "reality",
"grpcSettings": { "serviceName": "grpc" },
"realitySettings": {
"show": false,
"target": "www.cloudflare.com:443",
"serverNames": ["www.cloudflare.com"],
"privateKey": "PRIVATE_KEY_X25519",
"shortIds": ["b2c3d4e5"]
}
}
},
{
"tag": "vless-xhttp",
"listen": "0.0.0.0",
"port": 2096,
"protocol": "vless",
"settings": { "clients": [], "decryption": "none" },
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
"streamSettings": {
"network": "xhttp",
"security": "reality",
"xhttpSettings": { "path": "/xhttp", "mode": "auto" },
"realitySettings": {
"show": false,
"target": "www.cloudflare.com:443",
"serverNames": ["www.cloudflare.com"],
"privateKey": "PRIVATE_KEY_X25519",
"shortIds": ["c3d4e5f6"]
}
}
}
],
"outbounds": [
{ "tag": "DIRECT", "protocol": "freedom" },
{ "tag": "BLOCK", "protocol": "blackhole" }
],
"routing": { "rules": [
{ "ip": ["geoip:private"], "outboundTag": "BLOCK" },
{ "domain": ["geosite:private", "geosite:category-ads-all"], "outboundTag": "BLOCK" },
{ "protocol": ["bittorrent"], "outboundTag": "BLOCK" }
]}
}
gRPC работает без
flow(vision только для raw-TCP);serviceNameсовпадает у сервера и клиента. xHTTP:mode=auto/packet-up/stream-up, хорош за CDN.clients: []заполнит панель.⚠️ Проверено на xray 26.3.27 (живой прогон): все три транспорта работают (HTTP 200 с туннеля), но ядро помечает gRPC как
deprecated(«migrate to XHTTP stream-up H2»). Вывод: для не-raw входа приоритет у XHTTP (он развивается и лучше за CDN), gRPC как дополнительный вариант, пока работает. raw+Vision душится ТСПУ (см. «СУПЕР-АВТОВЫБОР»).
Как отдать клиенту в Remnawave
- В Config Profile ноды: три инбаунда выше (массив
inbounds). - Включите все три на ноде (Nodes → галочки inbounds).
- Создайте три Host'а, по одному на инбаунд: Remark «🇩🇪 DE · TCP», «🇩🇪 DE · gRPC», «🇩🇪 DE · xHTTP», Address = домен/IP ноды, Inbound = соответствующий. Порт подтянется из инбаунда.
- Добавьте инбаунды в нужные сквады (иначе не появятся в подписке).
- Лишние транспорты можно скрыть (
is_hidden) и оставить только как запас/для «Автовыбора».
Так одна нода даёт сразу TCP/gRPC/xHTTP. Если зарезали один транспорт, клиент работает через другой. Это база для «Автовыбора» (см. «Балансировщики»).
Отпечаток (fingerprint) при создании Host обязателен
При создании Host в Remnawave есть поле Fingerprint (uTLS). Это не косметика: uTLS полностью переписывает TLS-ClientHello под выбранный браузер, чтобы DPI по TLS-отпечатку (JA3) видел «обычный браузер», а не прокси-клиент. Оставлять пустым нельзя: голый Go-отпечаток палится сразу.
⚠️
chromeне ставьте. Это самый массовый отпечаток: по нему в первую очередь и учат DPI-фильтры, а на части сборок Reality-нода с ним вообще не поднимается. По умолчанию ставьтеfirefox, в ротацию берите
| Значение | Когда |
|---|---|
firefox ⭐ |
рекомендуемый по умолчанию. Другой TLS-стек (NSS), реже попадает под chrome-ориентированные фильтры. |
qq ⭐ |
хорошая альтернатива/ротация: нестандартный отпечаток (стек QQ-браузера), который массовые фильтры обычно не трогают. |
⛔ chrome |
не использовать: самый палевный (по нему учат фильтры), и на части сборок нода с ним не стартует. |
safari / ios / android / edge |
под конкретную аудиторию/устройства, для разнообразия. |
randomized / random |
разный отпечаток на сессию, спасает от простых JA3-сигнатур, но «нестабильный» профиль сам по себе бывает заметен. |
Практика:
- Основной хост: firefox; второй/резервный хост той же ноды: qq. Разные отпечатки = живучесть при волне блокировок.
- ⛔️ Не ставьте chrome_pq (post-quantum): он ломает Reality (ошибка nil ecdhe_key).
- Если хост «лёг», первым делом смените fingerprint (firefox↔qq) и/или SNI: часто снимает блок без пересоздания ноды.
Где это в панели: Hosts → (ваш хост) → поле Fingerprint. Отпечаток живёт на хосте, а не в inbound: на один inbound можно повесить несколько хостов с разными отпечатками (и так держать ротацию).
firefox/qq, держите второй хост той же ноды с другим отпечатком для ротации.Открыть порты на ноде
ufw allow 443/tcp
ufw allow 8443/tcp
ufw allow 2096/tcp
ufw allow from PANEL_IP to any port 2222 proto tcp # node API только с панели
Дальше смотрите «Балансировщики»: как собрать сервис-зависимый «Автовыбор» поверх этих нод/транспортов.