--- title: 'Имитация подсети на базе Xray-core (10.0.0.0/8)' description: 'Создание распределённой частной сети с помощью Xray-core и обратного туннелирования' createdDate: 2026-03-20 tags: ['networking', 'guides', 'xray'] --- > **ТОЛЬКО ДЛЯ ОБРАЗОВАТЕЛЬНЫХ ЦЕЛЕЙ** > Этот проект разработан как техническая демонстрация возможностей маршрутизации Xray-core и имитации частных подсетей. Он не предназначен для обхода ограничений или незаконной деятельности. Используйте полученные знания ответственно и в рамках закона. В этом руководстве разберём, как объединить удалённые серверы в распределённую частную сеть с единым адресным пространством `10.0.0.0/8`. Для этого используются **Xray-core**, **TPROXY** и **обратное VLESS-туннелирование**. --- ## Архитектура и принцип работы ### Концепция виртуальной подсети Мы создаём «плоскую» сеть третьего уровня (Layer 3) поверх публичного интернета. Каждый узел служит шлюзом для своей подсети `/16` из приватного диапазона `10.0.0.0/8`: - **Сервер A (Hub / Portal)**: `10.1.0.0/16` - **Сервер B (Spoke / Bridge)**: `10.2.0.0/16` - **Сервер C (Spoke / Bridge)**: `10.3.0.0/16` Серверы и Docker-контейнеры взаимодействуют напрямую, будто находятся в одной локальной сети. ### Принцип перехвата трафика (TPROXY) В отличие от `REDIRECT`, который работает только с TCP и подменяет IP-адрес назначения на адрес прокси, **TPROXY** (Transparent Proxy) перехватывает и TCP-, и UDP-пакеты, сохраняя исходные IP-заголовки отправителя и получателя. - **Маркировка**: когда пакет для `10.x.x.x` попадает в цепочку `PREROUTING` или `OUTPUT` iptables, таблица `mangle` помечает его меткой `0x1`. - **Сохранение адреса**: входящий обработчик `tunnel` в Xray с опцией сокета `"sockopt": { "tproxy": "tproxy" }` извлекает исходный IP-адрес назначения из метаданных сокета и маршрутизирует пакет дальше. ### Политика маршрутизации (таблица 100) Метки сами по себе не меняют маршрут пакета. Чтобы направить трафик в Xray, настраивается маршрутизация по политикам (**Policy Routing**): 1. **Правило (`ip rule`)**: команда `ip rule add fwmark 0x1 lookup 100 priority 100` указывает ядру Linux направлять пакеты с меткой `0x1` в таблицу маршрутизации 100. 2. **Маршрут (`ip route`)**: таблица 100 содержит правило `ip route add local 0.0.0.0/0 dev lo table 100`, направляющее все помеченные пакеты на петлевой интерфейс (`dev lo`). 3. **Перехват**: Xray слушает порт `127.0.0.1:12345` с включённым TPROXY и принимает пакеты с loopback. 4. **Защита от петель**: исходящий трафик самого Xray маркируется меткой `"sockopt": { "mark": 255 }` (`0xff`). Это исключает его из правил перехвата и предотвращает зацикливание маршрутизации. --- ## 1. Подготовка и генерация ключей Сгенерируйте четыре уникальных UUID для защиты обратных туннелей VLESS между хабом и узлами: - `UUID_B_REVERSE`: служебный туннель управления для сервера B (Bridge) - `UUID_B_DIRECT`: передача данных для сервера B - `UUID_C_REVERSE`: служебный туннель управления для сервера C (Bridge) - `UUID_C_DIRECT`: передача данных для сервера C --- ## 2. Настройка маршрутизации хоста и TPROXY (routing.sh и before.rules) Перед запуском контейнеров Xray на каждом узле нужно включить маршрутизацию в ядре и настроить цепочки `mangle` в UFW. ### A. Настройка маршрутизации в ядре (routing.sh) Скрипт [`routing.sh`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/routing.sh) включает пересылку IPv4-пакетов (`ip_forward`), связывает метку `0x1` с таблицей 100 и направляет трафик из неё на петлевой интерфейс (`dev lo`). Запустите скрипт на **всех** серверах: ```bash #!/usr/bin/env bash set -euo pipefail echo "Applying routing configuration..." # 1. Enable IP Forwarding sudo sysctl -w net.ipv4.ip_forward=1 # 2. IP Rule for mark 0x1 -> table 100 if sudo ip rule show | grep -q 'fwmark 0x1 lookup 100'; then echo "IP rule for mark 0x1 already exists." else sudo ip rule add fwmark 0x1 lookup 100 priority 100 echo "IP rule added for mark 0x1." fi # 3. Local route in table 100 if sudo ip route show table 100 2>/dev/null | grep -q 'local default dev lo'; then echo "Local route in table 100 already exists." else sudo ip route add local 0.0.0.0/0 dev lo table 100 echo "Local route added to table 100." fi echo "Routing configuration applied successfully." ``` ### B. Настройка файрвола на хабе (a/before.rules) На **сервере A (Hub)** добавьте правила TPROXY в конец файла `/etc/ufw/before.rules` (после первой директивы `COMMIT`). Логика правил: 1. **Локальная подсеть**: пакеты для `10.1.0.0/16` обрабатываются стандартно. 2. **Внешний трафик**: пакеты за пределами `10.0.0.0/8` не затрагиваются. 3. **Метка Xray (`0xff`)**: собственный трафик Xray пропускается, чтобы исключить зацикливание. 4. **Перехват TPROXY**: TCP- и UDP-трафик к `10.0.0.0/8` направляется в Xray на `127.0.0.1:12345` с меткой `1`. Файл в репозитории: [`a/before.rules`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/a/before.rules) ```ini *mangle :XRAY - [0:0] :XRAY_MASK - [0:0] :DIVERT - [0:0] # --- PREROUTING CHAIN (Трафик от контейнеров и других узлов) --- -A XRAY -d 10.1.0.0/16 -j RETURN -A XRAY ! -d 10.0.0.0/8 -j RETURN -A XRAY -m mark --mark 0xff -j RETURN -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A PREROUTING -j XRAY # --- OUTPUT CHAIN (Трафик, создаваемый сам хостом) --- -A XRAY_MASK -d 10.1.0.0/16 -j RETURN -A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN -A XRAY_MASK -m mark --mark 0xff -j RETURN -A XRAY_MASK -p udp -j MARK --set-mark 1 -A XRAY_MASK -p tcp -j MARK --set-mark 1 -A OUTPUT -j XRAY_MASK # --- Оптимизация DIVERT --- -A DIVERT -j MARK --set-mark 1 -A DIVERT -j ACCEPT -I PREROUTING -p tcp -m socket -j DIVERT COMMIT *filter -A ufw-before-forward -s 10.1.0.0/16 -d 10.1.0.0/16 -j ACCEPT -A ufw-before-forward -s 10.1.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT -A ufw-before-input -s 10.1.0.0/16 -d 10.1.0.0/16 -j ACCEPT -A ufw-before-input -s 10.1.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT ``` ### C. Настройка файрвола на узлах Spoke (b/before.rules и c/before.rules) На **сервере B (Spoke)** и **сервере C (Spoke)** примените соответствующие файлы `/etc/ufw/before.rules`. Для сервера B (`10.2.0.0/16`) локальный трафик подсети `10.2.0.0/16` исключается (`-d 10.2.0.0/16 -j RETURN`), а пакеты к остальной части `10.0.0.0/8` (например, к `10.1.x.x` или `10.3.x.x`) перехватывает TPROXY и направляет через обратный VLESS-туннель на сервер A. Файлы в репозитории: [`b/before.rules`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/b/before.rules) и [`c/before.rules`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/c/before.rules) ```ini *mangle :XRAY - [0:0] :XRAY_MASK - [0:0] :DIVERT - [0:0] -A XRAY -d 10.2.0.0/16 -j RETURN -A XRAY ! -d 10.0.0.0/8 -j RETURN -A XRAY -m mark --mark 0xff -j RETURN -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A PREROUTING -j XRAY -A XRAY_MASK -d 10.2.0.0/16 -j RETURN -A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN -A XRAY_MASK -m mark --mark 0xff -j RETURN -A XRAY_MASK -p udp -j MARK --set-mark 1 -A XRAY_MASK -p tcp -j MARK --set-mark 1 -A OUTPUT -j XRAY_MASK -A DIVERT -j MARK --set-mark 1 -A DIVERT -j ACCEPT -I PREROUTING -p tcp -m socket -j DIVERT COMMIT *filter -A ufw-before-forward -s 10.2.0.0/16 -d 10.2.0.0/16 -j ACCEPT -A ufw-before-forward -s 10.2.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT -A ufw-before-input -s 10.2.0.0/16 -d 10.2.0.0/16 -j ACCEPT -A ufw-before-input -s 10.2.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT ``` Перезагрузите правила файрвола на каждом узле командой `sudo ufw reload`. --- ## 3. Настройка узлов Xray-core (xray.jsonc) ### A. Конфигурация хаба (a/xray.jsonc) Хаб слушает публичный порт 443 по протоколам VLESS и XTLS-Vision. Он связывает входящие соединения обратных туннелей (`reverse-b`, `reverse-c`) с правилами маршрутизации для подсетей `/16`. Файл в репозитории: [`a/xray.jsonc`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/a/xray.jsonc) ```jsonc { "inbounds": [ { "port": 443, "protocol": "vless", "tag": "proxy-direct", "settings": { "clients": [ { "id": "UUID_B_REVERSE", "reverse": { "tag": "reverse-b" } }, { "id": "UUID_B_DIRECT" }, { "id": "UUID_C_REVERSE", "reverse": { "tag": "reverse-c" } }, { "id": "UUID_C_DIRECT" } ] } }, { "port": 12345, "listen": "127.0.0.1", "protocol": "tunnel", "tag": "proxy-enclave", "streamSettings": { "sockopt": { "tproxy": "tproxy", "mark": 255 } } } ], "routing": { "rules": [ { "ip": ["10.2.0.0/16"], "outboundTag": "reverse-b" }, { "ip": ["10.3.0.0/16"], "outboundTag": "reverse-c" } ] } } ``` ### B. Конфигурация узлов Spoke (b/xray.jsonc) Узел Spoke устанавливает клиентские соединения VLESS к серверу A (`A-EXTERNAL-IP`), поддерживает постоянный обратный туннель для входящих запросов и передаёт исходящий трафик `10.0.0.0/8`. Файлы в репозитории: [`b/xray.jsonc`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/b/xray.jsonc) и [`c/xray.jsonc`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/c/xray.jsonc) ```jsonc { "outbounds": [ { "protocol": "vless", "tag": "forward-a-reverse", "settings": { "address": "A-EXTERNAL-IP", "id": "UUID_B_REVERSE", "reverse": { "tag": "reverse-b" } } }, { "protocol": "vless", "tag": "forward-a", "settings": { "address": "A-EXTERNAL-IP", "id": "UUID_B_DIRECT" } } ], "routing": { "rules": [ { "inboundTag": ["proxy-enclave"], "outboundTag": "forward-a" }, { "inboundTag": ["reverse-b"], "outboundTag": "forward-direct" }, { "ip": ["10.2.0.0/16"], "outboundTag": "forward-direct" }, { "ip": ["10.0.0.0/8"], "outboundTag": "forward-a" } ] } } ``` --- ## Материалы и ссылки Примеры конфигураций с Docker Compose ([`a/docker-compose.yaml`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/a/docker-compose.yaml) и [`b/docker-compose.yaml`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/b/docker-compose.yaml)): - [Репозиторий xray-core-subnet-mimicry на GitHub](https://github.com/deytenit/xray-core-subnet-mimicry/tree/main) Документация: - [Официальная документация Xray-core](https://xtls.github.io/) - [Как устроен TPROXY (блог Cloudflare)](https://blog.cloudflare.com/how-we-built-spectrum/) - [Документация по TPROXY в ядре Linux](https://www.kernel.org/doc/Documentation/networking/tproxy.txt)