Этот гайд проведет вас через все этапы настройки сервера с нуля.
Ознакомьтесь с документацией.
sudo apt update && sudo apt upgrade -y
sudo apt install curl wget unzip git ufw socat jq certbot python3-certbot-nginx haproxy speedtest-cli dnsutils -y
wget -qO - https://dl.xanmod.org/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes
echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | sudo tee /etc/apt/sources.list.d/xanmod-release.list
sudo apt update && sudo apt upgrade -y
После обновления рекомендуется сбросить hosts. Если при подключении возникает ошибка Host key verification failed, удалите строку с IP сервера в этом файле (на Windows)
C:\Users\user\.ssh\known_hosts
wget -qO - https://dl.xanmod.org/check_x86-64_psabi.sh | awk -f -
sudo apt install linux-xanmod-edge-x64v3 -y
sudo apt install linux-xanmod-edge-x64v2 -y
sudo apt install linux-xanmod-edge-x64v1 -y
Перезагрузите сервер!
reboot now
nano /etc/sysctl.conf
Вставьте в конец файла (включение BBR):
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
Вставьте в конец файла (отключение ipv6):
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
sudo sysctl -p
depmod -a
modinfo tcp_bbr
nano /etc/systemd/resolved.conf
Измените/добавьте DNS:
[Resolve]
DNS=1.1.1.1 8.8.8.8
sudo systemctl restart systemd-resolved
resolvectl status
sudo curl -fsSL https://get.docker.com | sh
mkdir /opt/remnawave && cd /opt/remnawave
curl -o docker-compose.yml https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/docker-compose-prod.yml
curl -o .env https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/.env.sample
sed -i "s/^JWT_AUTH_SECRET=.*/JWT_AUTH_SECRET=$(openssl rand -hex 64)/" .env && sed -i "s/^JWT_API_TOKENS_SECRET=.*/JWT_API_TOKENS_SECRET=$(openssl rand -hex 64)/" .env
sed -i "s/^METRICS_PASS=.*/METRICS_PASS=$(openssl rand -hex 64)/" .env && sed -i "s/^WEBHOOK_SECRET_HEADER=.*/WEBHOOK_SECRET_HEADER=$(openssl rand -hex 64)/" .env
pw=$(openssl rand -hex 24) && sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$pw/" .env && sed -i "s|^\\(DATABASE_URL=\\\"postgresql://postgres:\\)[^\\@]*\\(@.*\\)|\\1$pw\\2|" .env
cd /opt/remnawave && nano .env
cd /opt/remnawave && docker compose down remnawave && docker compose up -d
mkdir -p /opt/remnawave/subscription && cd /opt/remnawave/subscription && nano docker-compose.yml
Вставьте содержимое:
services:
remnawave-subscription-page:
image: remnawave/subscription-page:latest
container_name: remnawave-subscription-page
hostname: remnawave-subscription-page
restart: always
env_file:
- .env
ports:
- '127.0.0.1:3010:3010'
networks:
- remnawave-network
volumes:
- ./app-config.json:/opt/app/frontend/assets/app-config.json
networks:
remnawave-network:
driver: bridge
external: true
cd /opt/remnawave/subscription && nano .env
APP_PORT=3010
REMNAWAVE_PANEL_URL=http://remnawave:3000
META_TITLE="Subscription page"
META_DESCRIPTION="Subscription page description"
cd /opt/remnawave/subscription && docker compose up -d
curl https://get.acme.sh | sh -s email=my@email.com && source ~/.bashrc
Создайте директорию для nginx.
mkdir -p /opt/remnawave/nginx
Получите сертификаты для панели и подписки.
acme.sh --issue --standalone -d 'panel.yourdomain.com' --key-file /opt/remnawave/nginx/privkey.key --fullchain-file /opt/remnawave/nginx/fullchain.pem --alpn --tlsport 8443
acme.sh --issue --standalone -d 'sub.yourdomain.com' --key-file /opt/remnawave/nginx/sub_privkey.key --fullchain-file /opt/remnawave/nginx/sub_fullchain.pem --alpn --tlsport 8443
cd /opt/remnawave/nginx && nano nginx.conf
Скопируйте полный конфиг для Standalone.
upstream remnawave {
server remnawave:3000;
}
upstream remnawave-subscription-page {
server remnawave-subscription-page:3010;
}
server {
server_name panel.yourdomain.com;
listen 443 ssl reuseport;
listen [::]:443 ssl reuseport;
http2 on;
location / {
proxy_http_version 1.1;
proxy_pass http://remnawave;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# SSL Configuration (Mozilla Intermediate Guidelines)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_certificate "/etc/nginx/ssl/fullchain.pem";
ssl_certificate_key "/etc/nginx/ssl/privkey.key";
ssl_trusted_certificate "/etc/nginx/ssl/fullchain.pem";
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
}
server {
server_name sub.yourdomain.com;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
location / {
proxy_http_version 1.1;
proxy_pass http://remnawave-subscription-page;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# SSL Configuration (Mozilla Intermediate Guidelines)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_certificate "/etc/nginx/ssl/sub_fullchain.pem";
ssl_certificate_key "/etc/nginx/ssl/sub_privkey.key";
ssl_trusted_certificate "/etc/nginx/ssl/sub_fullchain.pem";
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_reject_handshake on;
}
Docker Compose для Nginx (Standalone)
services:
remnawave-nginx:
image: nginx:1.28
container_name: remnawave-nginx
hostname: remnawave-nginx
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./fullchain.pem:/etc/nginx/ssl/fullchain.pem:ro
- ./privkey.key:/etc/nginx/ssl/privkey.key:ro
- ./subdomain_fullchain.pem:/etc/nginx/ssl/sub_fullchain.pem:ro
- ./subdomain_privkey.key:/etc/nginx/ssl/sub_privkey.key:ro
restart: always
ports:
- '0.0.0.0:443:443'
networks:
- remnawave-network
networks:
remnawave-network:
name: remnawave-network
driver: bridge
external: true
Создайте директорию для nginx.
mkdir -p /opt/remnawave/nginx
Создайте переменные окружения для подключения к Cloudflare.
export CF_Token="ваш_токен"
export CF_Account_ID="ваш_account_id"
Получите wildcard сертификат.
acme.sh --issue --dns dns_cf \
-d '.yourdomain.com' \
-d '*.yourdomain.com' \
--key-file /opt/remnawave/nginx/wildcard.key \
--fullchain-file /opt/remnawave/nginx/wildcard.pem
Скопируйте полный конфиг для Wildcard.
upstream remnawave {
server remnawave:3000;
}
upstream remnawave-subscription-page {
server remnawave-subscription-page:3010;
}
server {
server_name panel.yourdomain.com;
listen 443 ssl reuseport;
listen [::]:443 ssl reuseport;
http2 on;
location / {
proxy_http_version 1.1;
proxy_pass http://remnawave;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# SSL Configuration (Mozilla Intermediate Guidelines)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_certificate "/etc/nginx/ssl/fullchain.pem";
ssl_certificate_key "/etc/nginx/ssl/privkey.key";
ssl_trusted_certificate "/etc/nginx/ssl/fullchain.pem";
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
}
server {
server_name sub.yourdomain.com;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
location / {
proxy_http_version 1.1;
proxy_pass http://remnawave-subscription-page;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# SSL Configuration (Mozilla Intermediate Guidelines)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_certificate "/etc/nginx/ssl/fullchain.pem";
ssl_certificate_key "/etc/nginx/ssl/privkey.key";
ssl_trusted_certificate "/etc/nginx/ssl/fullchain.pem";
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_reject_handshake on;
}
Docker Compose для Nginx (Wildcard)
services:
remnawave-nginx:
image: nginx:1.28
container_name: remnawave-nginx
hostname: remnawave-nginx
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./wildcard.pem:/etc/nginx/ssl/fullchain.pem:ro
- ./wildcard.key:/etc/nginx/ssl/privkey.key:ro
restart: always
ports:
- '0.0.0.0:443:443'
networks:
- remnawave-network
networks:
remnawave-network:
name: remnawave-network
driver: bridge
external: true
docker compose up -d
sudo curl -fsSL https://get.docker.com | sh
mkdir -p /var/log/remnanode
sudo bash -c 'cat > /etc/logrotate.d/remnanode <<EOF
/var/log/remnanode/*.log {
size 50M
rotate 5
compress
missingok
notifempty
copytruncate
}
EOF'
mkdir /opt/remnanode && cd /opt/remnanode && nano docker-compose.yml
services:
remnanode:
container_name: remnanode
image: remnawave/node:latest
restart: always
network_mode: host
environment:
- NODE_PORT=2222
- SECRET_KEY="supersecretkey"
volumes:
- '/var/log/remnanode:/var/log/remnanode'
docker compose up -d
bash <(curl -fsSL git.new/install)
nano /opt/tblocker/config.yaml
# Файл логов для мониторинга
LogFile: "/var/log/remnanode/access.log"
# Продолжительность блокировки в минутах
BlockDuration: 10
# Тег, используемый для идентификации торрент-трафика в логах
TorrentTag: "TORRENT"
# Файрволл для блокировки (iptables, nft)
BlockMode: "iptables"
# IP-адреса для обхода блокировки
BypassIPS:
- "127.0.0.1"
- "::1"
# Директория для хранения данных о блокировке
StorageDir: "/opt/tblocker"
# Регулярное выражение для обработки имени пользователя в вебхуках
UsernameRegex: "^(.+)$"
systemctl start tblocker
journalctl -u tblocker -f --no-pager
В конфиг Xray добавьте правило маршрутизации routing:
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "TORRENT"
}
И соответствующий outbound:
{
"protocol": "blackhole",
"tag": "TORRENT"
}
bash <(curl -fsSL https://raw.githubusercontent.com/distillium/warp-native/main/install.sh)
ansible-galaxy install themelbine.warp_native
Пример:
- hosts: warp_servers
become: yes
roles:
- themelbine.warp_native
vars:
warp_native_state: present
warp_native_modify_resolv: true
warp_native_temp_nameservers:
- "1.1.1.1"
- "8.8.8.8"
Добавьте этот блок в раздел outbounds вашего конфига Xray:
{
"tag": "warp-out",
"protocol": "freedom",
"settings": {},
"streamSettings": {
"sockopt": {
"interface": "warp",
"tcpFastOpen": true
}
}
}
Добавьте этот блок в раздел routing вашего конфига Xray:
domain: Прописать домены (или geosite) для маршрутизации определенных сайтов.
inboundTag: Прописать ваши инбаунды "Node-1" и "Node-2", чтобы весь их трафик пустить через WARP
{
"type": "field",
"domain": ["netflix.com", "youtube.com", "geosite:category-ru"],
"inboundTag": ["Node-1", "Node-2"],
"outboundTag": "warp-out"
}
Создайте страницу-заглушку sni.html или скопируйте предложенную:
nano /opt/remnawave/nginx/html/sni.html
Загрузка содержимого sni.html...
Пример docker-compose.yml для nginx (в режиме hosts):
services:
remnawave-nginx:
image: nginx:1.28
container_name: remnawave-nginx
hostname: remnawave-nginx
restart: always
volumes:
- ./html:/usr/share/nginx/html/custom:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./wildcard.pem:/etc/nginx/ssl/wildcard.pem:ro
- ./wildcard.key:/etc/nginx/ssl/wildcard.key:ro
network_mode: "host"
Пример docker-compose.yml для nginx (существующая сеть с панелью):
services:
remnawave-nginx:
image: nginx:1.28
container_name: remnawave-nginx
hostname: remnawave-nginx
restart: always
ports:
- '127.0.0.1:9443:9443'
- '0.0.0.0:443:443'
volumes:
- ./html:/usr/share/nginx/html/custom:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./wildcard.pem:/etc/nginx/ssl/wildcard.pem:ro
- ./wildcard.key:/etc/nginx/ssl/wildcard.key:ro
networks:
- remnawave-network
networks:
remnawave-network:
name: remnawave-network
driver: bridge
external: true
Добавьте секцию сервера в nginx.conf
SNI_DOMAIN gateway.domain.com
FALLBACK_PORT 9443
CERT_PATH /etc/nginx/ssl/fullchain.pem
KEY_PATH /etc/nginx/ssl/privkey.key
# --- SNI FALLBACK (SNI_DOMAIN) ---
server {
server_name SNI_DOMAIN;
listen FALLBACK_PORT ssl proxy_protocol;
http2 on;
set_real_ip_from 127.0.0.1;
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
real_ip_header proxy_protocol;
root /usr/share/nginx/html/custom;
index sni.html;
# Логика обработки запросов
location = /sni.html {
add_header Cache-Control "no-store, no-cache, must-revalidate";
log_not_found off;
}
location / {
# Если файл не найден - редирект на именованный файл /sni.html
try_files \$uri \$uri/ /sni.html;
add_header Cache-Control "no-store, no-cache, must-revalidate";
}
# SSL Configuration (Mozilla Intermediate Guidelines)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
# Пути сертификатов (внутри контейнера)
ssl_certificate "CERT_PATH";
ssl_certificate_key "KEY_PATH";
ssl_trusted_certificate "CERT_PATH";
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
}
Перезагрузите docker nginx:
cd /opt/remnawave/nginx && docker compose down && docker compose up -d
Измените ваш streamSettings в inbounds вашего конфига Xray:
Необходимо установить xver 1, так как в nginx включен proxy_protocol, чтобы логи nginx определяли реальный IP клиента, открывшего адрес заглушки.
В target (он же dest) указываем локальный адрес и порт заглушки.
В serverNames указываем domain заглушки.
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"show": false,
"xver": 1,
"target": "127.0.0.1:9443",
"shortIds": [
""
],
"publicKey": "",
"privateKey": "",
"serverNames": [
"gateway.domain.com"
]
}
}
Эта система позволяет автоматически переключать DNS-запись на наименее загруженную ноду.
Установите зависимости:
apt install python3-pip python3-psutil -y || pip3 install psutil --break-system-packages
Создайте папку:
mkdir -p /opt/remnawave-balancer
Скачайте или создайте monitor.py:
Загрузка содержимого monitor.py...
Создайте сервис и запустите:
cat <<EOF > /etc/systemd/system/remnawave-monitor.service
[Unit]
Description=Remnawave Node Monitor
After=network.target
[Service]
User=root
WorkingDirectory=/opt/remnawave-balancer
ExecStart=/usr/bin/python3 /opt/remnawave-balancer/monitor.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Запускаем демон
systemctl daemon-reload && systemctl enable --now remnawave-monitor
Открываем порт для Balancer (Master-сервер)
ufw allow from 1.1.1.1 to any port 5050 proto tcp comment 'Master Balancer'
Установите зависимости:
apt install python3-requests -y
mkdir -p /opt/remnawave-balancer
Скачайте или создайте balancer.py:
Загрузка содержимого balancer.py...
Создайте файл nodes.json со списком серверов:
nano /opt/remnawave-balancer/nodes.json
[
{
"name": "Node-1",
"ip": "1.1.1.1",
"port": 5050
}
]
Создайте сервис и запустите:
# Создаем сервис
cat <<EOF > /etc/systemd/system/remnawave-balancer.service
[Unit]
Description=Remnawave DNS Balancer
After=network.target
[Service]
User=root
WorkingDirectory=/opt/remnawave-balancer
ExecStart=/usr/bin/python3 /opt/remnawave-balancer/balancer.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
Запускаем демон
systemctl daemon-reload && systemctl enable --now remnawave-balancer
Просмотр логов
tail -f /var/log/remnawave-balancer.log
Первым пунктом необходимо настроить конфигурацию Xray на зарубежной ноде.
Измените target, serverNames, сгенерируйте ключи publicKey и privateKey
Запомните publicKey вашего инбаунда, он понадобится при настройке RU ноды.
{
"log": {
"error": "/var/log/remnanode/error.log",
"access": "/var/log/remnanode/access.log",
"loglevel": "error"
},
"inbounds": [
{
"tag": "Vless TCP Reality EU",
"port": 443,
"listen": "0.0.0.0",
"protocol": "vless",
"settings": {
"clients": [],
"decryption": "none"
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls",
"quic"
]
},
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"show": false,
"xver": 0,
"target": "example.com:443",
"shortIds": [
""
],
"publicKey": "12345678qwerty",
"privateKey": "87654321",
"serverNames": [
"example.com"
]
}
}
}
],
"outbounds": [
{
"tag": "DIRECT",
"protocol": "freedom"
},
{
"tag": "BLOCK",
"protocol": "blackhole"
}
],
"routing": {
"rules": [
{
"ip": [
"geoip:private"
],
"type": "field",
"outboundTag": "BLOCK"
},
{
"type": "field",
"domain": [
"geosite:private"
],
"outboundTag": "BLOCK"
},
{
"type": "field",
"protocol": [
"bittorrent"
],
"outboundTag": "BLOCK"
}
]
}
}
Вторым этапом необходимо создать пользователя Bridge (он будет сервисным пользователем, не давайте ключи для подключения к данному профилю!).
Запомните VLESS UUID пользователя Bridge, он понадобится при настройке RU ноды.
Третьим этапом необходимо настроить конфигурацию Xray на RU ноде.
В inbounds Vless TCP Reality RU измените target, serverNames, сгенерируйте ключи publicKey и privateKey
В outbounds vnext-outbound замените IP/domain вашей EU ноды, VLESS UUID пользователя Bridge, serverNames EU ноды.
В routing добавьте правила маршрутизации. geoip:ru и geosite:category-ru пустите напрямую с RU ноды, inboundTag укажите ваш inbound RU ноды, чтобы весь оставшийся трафик ушел на EU ноду.
{
"log": {
"error": "/var/log/remnanode/error.log",
"access": "/var/log/remnanode/access.log",
"loglevel": "error"
},
"inbounds": [
{
"tag": "Vless TCP Reality RU",
"port": 443,
"listen": "0.0.0.0",
"protocol": "vless",
"settings": {
"clients": [],
"decryption": "none"
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls",
"quic"
]
},
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"target": "example.com:443",
"show": false,
"xver": 0,
"shortIds": [
""
],
"publicKey": "REPLACE_WITH_YOUR_PUBLIC_KEY",
"privateKey": "REPLACE_WITH_YOUR_PRIVATE_KEY",
"serverNames": [
"example.com"
]
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "DIRECT"
},
{
"protocol": "blackhole",
"tag": "BLOCK"
},
{
"protocol": "vless",
"tag": "vnext-outbound",
"settings": {
"vnext": [
{
"address": "IP_вашей_ноды_EU",
"port": 443,
"users": [
{
"id": "VLESS UUID_пользователя_Bride",
"flow": "xtls-rprx-vision",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"serverName": "example.com",
"publicKey": "publicKey_вашей_ноды_EUы",
"spiderX": "/"
}
}
}
],
"routing": {
"rules": [
{
"ip": [
"geoip:private"
],
"outboundTag": "BLOCK",
"type": "field"
},
{
"domain": [
"geosite:private"
],
"outboundTag": "BLOCK",
"type": "field"
},
{
"protocol": [
"bittorrent"
],
"outboundTag": "BLOCK",
"type": "field"
},
{
"ip": [
"geoip:ru"
],
"outboundTag": "DIRECT",
"type": "field"
},
{
"domain": [
"geosite:category-ru"
],
"outboundTag": "DIRECT",
"type": "field"
},
{
"type": "field",
"inboundTag": [
"Vless TCP Reality RU"
],
"outboundTag": "vnext-outbound"
}
]
}
}