Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 

Repository files navigation

Advanced Configurations & Examples

Детальные конфигурации для продвинутых сценариев: Xray inbound, sing-box routing, DNS, WireGuard, мониторинг и оптимизация.

Во всех примерах используются плейсхолдеры:

  • SERVER_IP — публичный IP-адрес VPS;
  • ROUTER_IP — IP-адрес роутера в локальной сети (по умолчанию 192.168.1.1);
  • UUID — идентификатор клиента VLESS;
  • PRIVATE_KEY / PUBLIC_KEY — ключи Reality;
  • SHORT_ID — short ID Reality;
  • SNI_DOMAIN — домен прикрытия (например, www.amazon.com).

Содержание

  1. Xray Inbound (VLESS + Reality + Vision)
  2. Sing-box Config для Podkop (selective routing)
  3. Bypass Rules (исключение трафика из туннеля)
  4. WireGuard (удалённый доступ к роутеру)
  5. AdGuard Home + Xray
  6. Списки маршрутизации (selective mode)
  7. Тестирование и отладка
  8. Мониторинг и логирование
  9. Оптимизация производительности
  10. Управление 3x-ui через API

1. Xray Inbound (VLESS + Reality + Vision)

1.1. JSON для 3x-ui (Raw Config)

Серверный inbound. На стороне сервера в realitySettings хранится только приватный ключ; публичный ключ передаётся клиенту отдельно (в ссылке vless:// или в клиентском конфиге).

{
  "inbounds": [
    {
      "port": 443,
      "protocol": "vless",
      "tag": "vless-reality",
      "settings": {
        "clients": [
          {
            "id": "UUID",
            "email": "client-1",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": false,
          "dest": "SNI_DOMAIN:443",
          "xver": 0,
          "serverNames": [
            "SNI_DOMAIN"
          ],
          "privateKey": "PRIVATE_KEY",
          "maxTimeDiff": 70000,
          "shortIds": [
            "SHORT_ID"
          ]
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    }
  ]
}

1.2. Генерация ключей Reality

Способ 1 — через панель 3x-ui:

  1. Inbound List → выбрать inbound → Edit.
  2. В секции Security нажать Get New Cert.
  3. Панель сгенерирует пару ключей (приватный остаётся на сервере, публичный нужен клиенту).
  4. Скопировать значения.

Способ 2 — через CLI (X25519, формат для Reality):

# На VPS
xray x25519
# Вывод:
#   Private key: ...   → privateKey в серверный конфиг
#   Public key:  ...   → publicKey в клиентский конфиг

Reality использует ключи X25519, а не ECDSA prime256v1. Команда openssl ecparam для генерации ключей Reality не подходит — используйте xray x25519.

Генерация short ID:

openssl rand -hex 8

2. Sing-box Config для Podkop (selective routing)

2.1. Структура конфига

{
  "log": {
    "level": "info",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "tun",
      "tag": "tun-in",
      "inet4_address": "198.18.0.1/15",
      "auto_route": false,
      "strict_route": false,
      "sniff": true,
      "sniff_override_destination": false,
      "domain_strategy": "prefer_ipv4"
    },
    {
      "type": "dns",
      "tag": "dns-in",
      "listen": "127.0.0.1",
      "listen_port": 7874
    }
  ],
  "outbounds": [
    {
      "type": "vless",
      "tag": "proxy",
      "server": "SERVER_IP",
      "server_port": 443,
      "uuid": "UUID",
      "flow": "xtls-rprx-vision",
      "tls": {
        "enabled": true,
        "server_name": "SNI_DOMAIN",
        "utls": {
          "enabled": true,
          "fingerprint": "chrome"
        },
        "reality": {
          "enabled": true,
          "public_key": "PUBLIC_KEY",
          "short_id": "SHORT_ID"
        }
      }
    },
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "dns",
      "tag": "dns-out"
    }
  ],
  "route": {
    "rules": [
      {
        "protocol": "dns",
        "outbound": "dns-out"
      },
      {
        "ip_is_private": true,
        "outbound": "direct"
      },
      {
        "rule_set": "blocked-domains",
        "outbound": "proxy"
      },
      {
        "outbound": "direct"
      }
    ],
    "auto_detect_interface": true,
    "override_android_vpn": true
  },
  "dns": {
    "servers": [
      {
        "tag": "proxydns",
        "address": "tcp+local://8.8.8.8:53",
        "detour": "proxy"
      },
      {
        "tag": "localdns",
        "address": "local"
      }
    ],
    "rules": [
      {
        "rule_set": "blocked-domains",
        "server": "proxydns"
      },
      {
        "server": "localdns"
      }
    ]
  }
}

В правилах route и dns теги серверов (proxydns, localdns) и rule_set должны совпадать буквально. Частая ошибка — несоответствие тегов (например, сервер объявлен как proxydns, а в правиле указан proxyns), из-за чего конфиг не загружается.

2.2. Расположение конфига на роутере

Точный путь зависит от версии Podkop. Проверить кандидатов:

cat /etc/podkop/config.json
cat /usr/share/podkop/config.json
cat /etc/sing-box/config.json

Редактирование и применение:

vi /etc/podkop/config.json
/etc/init.d/podkop restart

3. Bypass Rules (исключение трафика из туннеля)

Применяется для трафика, который должен идти напрямую: внутренние сервисы, PPTP/GRE-туннели, CDN.

3.1. Через sing-box (рекомендуется)

{
  "route": {
    "rules": [
      {
        "ip_cidr": [
          "203.0.113.45/32",
          "10.0.0.0/8"
        ],
        "outbound": "direct"
      }
    ]
  }
}

Адреса в примере — документационные (RFC 5737 203.0.113.0/24 и RFC 1918 10.0.0.0/8). Замените на фактические IP, которые требуется исключить.

3.2. Через policy-based routing на роутере

ssh root@ROUTER_IP
cat > /etc/firewall.user << 'EOF'
#!/bin/sh
# Исключение трафика к указанному IP из туннеля sing-box.
# Помечает пакеты меткой 0x100; политика маршрутизации
# направляет их в таблицу с прямым шлюзом.

DIRECT_IP="203.0.113.45"
GATEWAY="192.168.1.1"
MARK="0x100"
TABLE="100"

ip rule add fwmark "$MARK" lookup "$TABLE" 2>/dev/null
ip route replace default via "$GATEWAY" table "$TABLE"

iptables -t mangle -A PREROUTING -d "$DIRECT_IP" -j MARK --set-mark "$MARK"
EOF

chmod +x /etc/firewall.user
/etc/init.d/firewall restart

Способ 3.1 (через sing-box) предпочтительнее: он не зависит от структуры firewall и не конфликтует с правилами Podkop. Способ 3.2 — резервный, для случаев когда перехват происходит вне sing-box.


4. WireGuard (удалённый доступ к роутеру)

Безопасная альтернатива публичному SSH.

4.1. Подготовка пакетов и ключей

# На роутере (OpenWRT)
apk add wireguard-tools luci-proto-wireguard

mkdir -p /etc/wireguard
cd /etc/wireguard
umask 077

# Ключи сервера (роутера)
wg genkey | tee server_private.key | wg pubkey > server_public.key

# Ключи клиента
wg genkey | tee client_private.key | wg pubkey > client_public.key

# Pre-shared key (общий)
wg genpsk > preshared.key

4.2. Конфигурация интерфейса

UCI-конфиг не выполняет подстановку $(...). Значения ключей нужно вписать явно или подставить через скрипт.

SERVER_PRIV=$(cat /etc/wireguard/server_private.key)
CLIENT_PUB=$(cat /etc/wireguard/client_public.key)
PSK=$(cat /etc/wireguard/preshared.key)

cat >> /etc/config/network << EOF

config interface 'wg0'
    option proto 'wireguard'
    option private_key '$SERVER_PRIV'
    option listen_port '51820'
    list addresses '10.10.10.1/24'

config wireguard_wg0
    option description 'remote-client'
    option public_key '$CLIENT_PUB'
    option preshared_key '$PSK'
    list allowed_ips '10.10.10.2/32'
    option route_allowed_ips '1'
EOF

/etc/init.d/network restart
ip addr show wg0
wg show

4.3. Конфигурация клиента

[Interface]
PrivateKey = <содержимое client_private.key>
Address = 10.10.10.2/24
DNS = 192.168.1.1

[Peer]
PublicKey = <содержимое server_public.key>
PresharedKey = <содержимое preshared.key>
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs = 10.10.10.0/24, 192.168.1.0/24
PersistentKeepalive = 25

Endpoint указывает на публичный IP роутера. Для доступа к ресурсам локальной сети роутера в AllowedIPs включается её подсеть (192.168.1.0/24).

4.4. Firewall

cat >> /etc/config/firewall << 'EOF'

config zone
    option name 'wireguard'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'ACCEPT'
    list network 'wg0'

config forwarding
    option src 'wireguard'
    option dest 'lan'

config forwarding
    option src 'lan'
    option dest 'wireguard'

config rule
    option name 'Allow-WireGuard'
    option src 'wan'
    option proto 'udp'
    option dest_port '51820'
    option target 'ACCEPT'
EOF

/etc/init.d/firewall restart

Правило Allow-WireGuard необходимо: без него входящие UDP-пакеты на порт 51820 из WAN будут отброшены, и подключение не установится.


5. AdGuard Home + Xray

5.1. Установка на VPS

# Актуальную версию см. на https://github.com/AdguardTeam/AdGuardHome/releases
VERSION="v0.107.77"
wget "https://github.com/AdguardTeam/AdGuardHome/releases/download/${VERSION}/AdGuardHome_linux_amd64.tar.gz"
tar -xzf AdGuardHome_linux_amd64.tar.gz

5.2. Первичный запуск и настройка

# Запуск на loopback (не на публичном интерфейсе)
./AdGuardHome/AdGuardHome -h 127.0.0.1

Веб-интерфейс первичной настройки доступен на http://127.0.0.1:3000. После настройки:

  • порт DNS-сервера AdGuard Home — 53 (или иной, заданный в мастере);
  • Upstream DNS — 8.8.8.8, резервный 1.1.1.1;
  • в 3x-ui (Settings → DNS Settings) указать AdGuard Home как upstream: 127.0.0.1:53.

Web-порт (3000) и DNS-порт (53) — разные порты. Xray направляется на DNS-порт, а не на web-порт.

5.3. Автозапуск (systemd)

AdGuard Home поддерживает установку в качестве сервиса собственными средствами — это надёжнее ручного unit-файла:

./AdGuardHome/AdGuardHome -s install
systemctl status AdGuardHome

Управление:

./AdGuardHome/AdGuardHome -s start
./AdGuardHome/AdGuardHome -s stop
./AdGuardHome/AdGuardHome -s uninstall

6. Списки маршрутизации (selective mode)

Современные версии Podkop используют форматы community-листов (geosite, rule-set, текстовые списки доменов/подсетей). Точные пути и форматы зависят от версии — ориентироваться на интерфейс LuCI.

6.1. Списки доменов

# Домены, маршрутизируемые через туннель (proxy):
example-blocked-1.com
example-blocked-2.org

# Домены, идущие напрямую (direct):
*.lan
internal.example.local

6.2. Списки IP/подсетей

# Через туннель (proxy):
198.51.100.0/24

# Напрямую (direct):
192.168.0.0/16
10.0.0.0/8
172.16.0.0/12

Локальные диапазоны RFC 1918 (192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12) всегда должны идти напрямую, иначе сломается доступ к локальной сети.


7. Тестирование и отладка

7.1. Проверка Reality (со стороны клиента)

# 1. TLS handshake с доменом прикрытия — должен вернуть
#    валидный сертификат целевого сайта (SNI_DOMAIN)
openssl s_client -connect SERVER_IP:443 -servername SNI_DOMAIN </dev/null

# 2. TLS fingerprint — сравнить с эталоном браузера
curl -v --http2 https://tls.peet.ws/api/all
# Эталон: https://browserleaks.com/tls

# 3. Проверка DNS
curl 'https://dns.google/resolve?name=example.com'

# 4. Проверка IP выхода — должен совпадать с SERVER_IP
curl https://ifconfig.me

7.2. Отладка Podkop на роутере

# Уровень логирования в конфиге sing-box:
#   "log": { "level": "debug", "timestamp": true }
# (debug — только на время диагностики, не для постоянной работы)

/etc/init.d/podkop restart
logread -e podkop -f

7.3. Проверка FakeIP

# 1. Правила перехвата в nftables
nft list ruleset | grep -i tun

# 2. DNS-ответ должен содержать FakeIP из диапазона 198.18.0.0/15
dig @127.0.0.1 -p 7874 example.com

# 3. Записи conntrack для FakeIP во время активного трафика
cat /proc/net/nf_conntrack | grep '198.18' | head -5

8. Мониторинг и логирование

8.1. Логи Xray (3x-ui)

{
  "log": {
    "access": "/var/log/xray/access.log",
    "error": "/var/log/xray/error.log",
    "loglevel": "warning"
  }
}

warning достаточно для продакшена. info и debug увеличивают объём логов и нагрузку.

8.2. Ротация логов (logrotate)

cat > /etc/logrotate.d/xray << 'EOF'
/var/log/xray/*.log {
    daily
    rotate 7
    compress
    delaycompress
    notifempty
    missingok
    create 0640 root root
    sharedscripts
    postrotate
        systemctl reload 3x-ui > /dev/null 2>&1 || true
    endscript
}
EOF

8.3. Сбор метрик на роутере

cat >> /etc/crontabs/root << 'EOF'
0 * * * * echo "$(date '+\%F \%T'): $(free -m | awk '/Mem/{print $3"/"$2" MB"}')" >> /tmp/mem.log
EOF

/etc/init.d/cron restart

Для постоянного мониторинга предпочтительнее luci-app-statistics (collectd) — он даёт графики и не нагружает flash частыми записями.


9. Оптимизация производительности

9.1. Слабые роутеры (MT7628, 128 МБ RAM)

  1. Отключить неиспользуемые сервисы:

    /etc/init.d/dnsmasq stop   # только если DNS полностью обрабатывает sing-box

    uhttpd (LuCI) отключать не рекомендуется — теряется веб-управление. Достаточно ограничить его доступность по WAN через firewall.

  2. Использовать урезанные geo-базы (geoip-lite/geosite-lite) или текстовые списки доменов вместо полной базы — это основной потребитель RAM.

  3. Включить SQM для управления буфером (bufferbloat):

    apk add sqm-scripts luci-app-sqm
    # Настройка: LuCI → Network → SQM QoS

9.2. Производительные роутеры (Cudy TR3000 и аналоги)

  1. Увеличить TCP-буферы:

    cat > /etc/sysctl.d/99-network.conf << 'EOF'
    net.core.rmem_max=67108864
    net.core.wmem_max=67108864
    net.ipv4.tcp_rmem=4096 87380 33554432
    net.ipv4.tcp_wmem=4096 65536 33554432
    EOF
    sysctl -p /etc/sysctl.d/99-network.conf
  2. Включить BBR (если модуль доступен в сборке):

    modprobe tcp_bbr 2>/dev/null
    echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.d/99-network.conf
    sysctl -p /etc/sysctl.d/99-network.conf
    sysctl net.ipv4.tcp_congestion_control   # проверка

    BBR влияет на исходящие соединения самого роутера. На транзитный трафик, проходящий через туннель, основное влияние оказывает congestion control на VPS — BBR имеет смысл включать и там.


10. Управление 3x-ui через API

Базовый клиент на Python. Учётные данные и адрес панели передаются как параметры, не хранятся в коде.

import requests


class XUIClient:
    def __init__(self, base_url, username, password, verify_tls=True):
        self.base_url = base_url.rstrip("/")
        self.session = requests.Session()
        self.session.verify = verify_tls
        self._login(username, password)

    def _login(self, username, password):
        r = self.session.post(
            f"{self.base_url}/login",
            json={"username": username, "password": password},
            timeout=10,
        )
        r.raise_for_status()
        return r.json()

    def add_client(self, inbound_id, client_data):
        r = self.session.post(
            f"{self.base_url}/panel/api/inbounds/addClient",
            json={"id": inbound_id, "settings": client_data},
            timeout=10,
        )
        r.raise_for_status()
        return r.json()

    def subscription_url(self, sub_id):
        return f"{self.base_url}/sub/{sub_id}"


# Пример использования
client = XUIClient(
    base_url="https://SERVER_IP:2053",
    username="admin",
    password="CHANGE_ME",
    verify_tls=True,  # False только при self-signed сертификате
)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors