155 lines
11 KiB
Plaintext
155 lines
11 KiB
Plaintext
---
|
||
title: 'Имитация подсети Xray (10.0.0.0/8)'
|
||
description: 'Создание распределенной частной сети с использованием Xray-core и обратного туннелирования'
|
||
createdDate: 2026-03-20
|
||
tags: ['networking', 'xray', 'guide']
|
||
---
|
||
|
||
> **ТОЛЬКО ДЛЯ ОБРАЗОВАТЕЛЬНЫХ ЦЕЛЕЙ**
|
||
> Этот проект разработан как техническая демонстрация возможностей маршрутизации Xray-core и имитации частных подсетей. Он НЕ предназначен для обхода ограничений или незаконной деятельности. Используйте эти знания ответственно и в соответствии с местным законодательством.
|
||
|
||
Это руководство описывает, как развернуть распределенную инфраструктуру (например, для заметок или любого другого сервиса), используя непрерывную частную подсеть `10.0.0.0/8`, имитируемую на различных серверах с помощью **Xray-core** и **обратного туннелирования**.
|
||
|
||
## Технический разбор и архитектура
|
||
|
||
### Концепция виртуальной подсети
|
||
|
||
Мы создаем «плоскую сеть» (Layer 3) поверх публичного интернета. Каждый узел выступает в качестве полномочного шлюза для своего собственного сегмента `/16` из диапазона `10.0.0.0/8`. Это обеспечивает бесперебойную связь между серверами, как если бы они находились в одной локальной сети.
|
||
|
||
### Наука перехвата (TPROXY)
|
||
|
||
В отличие от `REDIRECT`, который работает только для TCP и изменяет IP-адрес назначения, **TPROXY** (Transparent Proxy) позволяет Xray перехватывать как TCP, так и UDP, сохраняя при этом исходные заголовки пакетов.
|
||
|
||
- **Механизм**: Когда пакет, предназначенный для `10.x.x.x`, попадает в цепочку `PREROUTING` или `OUTPUT`, таблица Linux Mangle помечает его меткой `0x1`.
|
||
- **Сохранение**: Входящий поток `tunnel` в Xray использует опцию сокета `tproxy` для чтения исходного IP-адреса назначения из метаданных сокета, что позволяет правильно маршрутизировать пакет.
|
||
|
||
### Политика маршрутизации (Таблица 100)
|
||
|
||
Хотя метки брандмауэра идентифицируют перехваченные пакеты, они сами по себе не изменяют путь маршрутизации. Чтобы перенаправить этот трафик в Xray, мы используем **Policy Routing**:
|
||
|
||
1. **Правило (`ip rule`)**: `ip rule add fwmark 1 lookup 100` предписывает сетевому стеку использовать пользовательскую таблицу маршрутизации для помеченных пакетов.
|
||
2. **Таблица (`ip route`)**: Таблица 100 настроена с параметром `local default dev lo`, что заставляет систему рассматривать все IP-адреса назначения как локальные и направлять их на интерфейс петли (loopback).
|
||
3. **Передача**: Xray, прослушивающий `127.0.0.1:12345` с опцией `tproxy`, перехватывает пакет с интерфейса loopback.
|
||
4. **Предотвращение петель**: Мы используем `mark: 255` в исходящих потоках Xray, чтобы исключить его собственный трафик из перехвата, предотвращая бесконечные циклы маршрутизации.
|
||
|
||
### Механизм обратного прокси
|
||
|
||
Для доступа к серверам за NAT (Spokes) из центрального хаба Xray использует сложную архитектуру обратного прокси:
|
||
|
||
- **Bridge (Spoke)**: Инициирует соединение с порталом. Он действует как клиент для туннеля, но функционально ведет себя как сервер после установления соединения.
|
||
- **Portal (Hub)**: Прослушивает входящие соединения от Bridge и использует «фиктивные домены» (Dummy Domains) для их идентификации, ретранслируя трафик через установленные туннели.
|
||
- **Мультиплексирование (Mux)**: Использует [Mux.cool](https://xtls.github.io/en/development/protocols/muxcool.html) для упаковки сотен виртуальных потоков в одно физическое TLS-соединение, что снижает накладные расходы и позволяет обходить тайм-ауты NAT.
|
||
|
||
## Руководство по настройке
|
||
|
||
### Этап 0: Предварительные требования (только для сервера А)
|
||
|
||
Серверу А (Hub) требуется действующий SSL-сертификат для XTLS-Vision. Направьте ваш домен (`A-DOMAIN`) на публичный IP сервера А и убедитесь, что сертификаты доступны (например, через Certbot) по адресу `/etc/letsencrypt/live/A-DOMAIN/`.
|
||
|
||
### Этап 1: Безопасность и идентификация
|
||
|
||
Для каждого соединения требуется уникальный UUID. Сгенерируйте 4 UUID для сопоставления следующих соединений:
|
||
|
||
- `UUID_B_REVERSE`: Управление туннелем для сервера B.
|
||
- `UUID_B_DIRECT`: Трафик данных для сервера B.
|
||
- `UUID_C_REVERSE`: Управление туннелем для сервера C.
|
||
- `UUID_C_DIRECT`: Трафик данных для сервера C.
|
||
|
||
### Этап 2: Настройка хоста
|
||
|
||
На **КАЖДОМ** узле сервера выполните следующее:
|
||
|
||
1. **Инициализация маршрутизации**: Запустите скрипт настройки маршрутизации для конфигурации параметров ядра и таблицы 100.
|
||
2. **Настройка брандмауэра**: Обновите `/etc/ufw/before.rules`. Вставьте специфические правила узла сразу после заголовка `*filter`. Эти правила обрабатывают логику таблицы `mangle`, необходимую для TPROXY.
|
||
3. **Перезагрузка**: Примените изменения с помощью `sudo ufw reload`.
|
||
|
||
### Этап 3: Развертывание
|
||
|
||
Обновите конфигурации `xray.jsonc`, указав сгенерированные UUID, ваш домен и публичные IP-адреса. Запустите стек с помощью `docker compose up -d`. На сервере А установка compose также инициализирует внутреннюю мостовую сеть для таких сервисов, как AdGuard и Nginx.
|
||
|
||
## Примеры конфигурации
|
||
|
||
### Сервер A: Хаб (10.1.0.0/16)
|
||
|
||
Хаб обрабатывает входы обратных туннелей и маршрутизирует трафик в соответствующий Spoke на основе диапазона 10.x.x.x.
|
||
Полная конфигурация доступна здесь: [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": "REPLACE_WITH_UUID_B_REVERSE", "reverse": { "tag": "reverse-b" } },
|
||
{ "id": "REPLACE_WITH_UUID_B_DIRECT" },
|
||
// ... повторите для других Spokes
|
||
],
|
||
},
|
||
},
|
||
{
|
||
"tag": "proxy-enclave",
|
||
"protocol": "tunnel",
|
||
"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 (10.2.0.0/16)
|
||
|
||
Spoke инициирует обратное соединение с Хабом и обрабатывает выход в локальную подсеть.
|
||
Полная конфигурация доступна здесь: [b/xray.jsonc](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/b/xray.jsonc)
|
||
|
||
```jsonc
|
||
{
|
||
"outbounds": [
|
||
{
|
||
"protocol": "vless",
|
||
"tag": "forward-a-reverse",
|
||
"settings": {
|
||
"address": "A-EXTERNAL-IP",
|
||
"id": "REPLACE_WITH_UUID_B_REVERSE",
|
||
"reverse": { "tag": "reverse-b" },
|
||
},
|
||
},
|
||
{
|
||
"protocol": "vless",
|
||
"tag": "forward-a",
|
||
"settings": {
|
||
"address": "A-EXTERNAL-IP",
|
||
"id": "REPLACE_WITH_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" },
|
||
],
|
||
},
|
||
}
|
||
```
|
||
|
||
## Ресурсы и ссылки
|
||
|
||
Для получения полного автоматизированного примера этой архитектуры посетите следующий репозиторий:
|
||
|
||
- [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)
|