惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
IT之家
IT之家
Google DeepMind News
Google DeepMind News
罗磊的独立博客
爱范儿
爱范儿
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
U
Unit 42
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
B
Blog
博客园 - 叶小钗
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Разделение исходящего и входящего трафика по разным IP-ад...
Андрей · 2026-06-24 · via Все публикации подряд на Хабре

Средний

9 мин

761

В наше непростое время... Хотя, к чему все это? Все в курсе. Переходим к технической части.

Многие знают, что XRAY умеет получать запрос от клиента на один ip адрес, а отправлять ответ с другого ip адреса. Документации на этот счет в интернете крайне немного (ну или я не умею искать). Есть образцы базовых настроек в примерах на GitHub проекта XTLS и несколько упоминаний о существовании такой фишки в статьях на Хабре без подробностей реализации. Я же попробую описать здесь теорию и настройку разделения входящего и исходящего трафика подробно и с примерами.

Зачем все это нужно?

  1. Теоретически, это усложняет поведенческий анализ трафика со стороны DPI. Паттерны ломаются и, в теории, это помогает обойти блокировки. Но это не точно.

  2. Если такая фича существует, ее нужно запилить и посмотреть как все это работает на практике. Чисто из научного интереса.

На чем будем настраивать?

На сервере стоит Angie (версия 1.11.6) в качестве реверсивного прокси, за ним прячется панель 3x-ui (версия 3.4.0), которая управляет XRAY (версия 26.6.22). Будем исходить из этой конфигурации.

Можно ли реализовать разделение трафика без реверсивного прокси?

Все упирается в расшифровку двух разных потоков SSL в рамках одного входящего подключения в XRAY. Умеет он такое или нет, я информации не нашел. В настройках подключения есть возможность указать несколько SSL сертификатов, но нет возможности указать несколько SNI, так что возможно, это будет работать только для ip без доменных имен. Скажу честно, я не пробовал.

Важная деталь: у Вашего сервера обязательно должно быть два внешних ip адреса. Желательно из разных подсетей, хотя различие подсетей не играет никакой роли. Большинство хостеров раздает несколько ip на один VDS. У меня эта опция стоит 5 руб в день за каждый дополнительный адрес. Можно делать настройки напрямую с ip адресами, но, для красоты и наглядности, предлагаю к каждому ip привязать свой поддомен. У нас это будут upload.domain.com и download.domain.com. Привязка делается в настройках DNS зоны у регистратора доменов. Интересное наблюдение. Несмотря на то, что оба моих ip адреса на одном и том же VDS, выданы одним и тем же хостером и находятся физически в одном и том же датацентре, 2ip.ru показывает, что один ip адрес расположен в Москве, а второй в Новосибирске, что забавно.

Можно использовать разные VDS для разделения трафика. Физически это могут быть разные машины в разных дата-центрах в разных странах на разных континентах. Для этого нужно с проксировать весь входящий трафик с download сервера на upload сервер с помощью любого реверсивного прокси. На download сервере даже XRAY не нужен. О том как запилить такое проксирование есть ролик на замедленном Youtube на примере Caddy. Но тут есть несколько моментов.

  1. Если оба сервера находятся внутри локальной сети в одном дата-центре, то это ничем не отличается от варианта два ip на одном VDS, а если нет разницы, зачем платить больше?

  2. Если оба сервера находятся в разных дата-центрах, мы получаем дополнительные накладные расходы в виде задержек трафика между серверами без видимой целесообразности, ибо DPI ломается от различия ip адресов, а не от их географического расположения. Опять же, два сервера минимум в два раза дороже, чем один сервер с двумя ip адресами.

Поэтому из экономии будем рассматривать вариант один сервер - два ip.

Итак, погнали. Настраиваем Angie.

Создаем файл xray.conf в папке /etc/angie/http.d. Имя файла может быть любым. Расширение строго conf

xray.conf
server {
    listen x.x.x.1:443 ssl;
    server_name upload.domain.com;

    http2 on;

    ssl_certificate /etc/letsencrypt/live/upload.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/upload.domain.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    resolver 1.1.1.1 8.8.8.8 valid=300s;
    resolver_timeout 5s;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets on; 

    client_header_timeout 5m;
    keepalive_timeout 5m;

   location /api/v1/data/ {
        client_max_body_size 0;
        
        proxy_pass http://unix:/dev/shm/xrxhd.socket;
        
        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_http_version 1.1;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_cache off;
        
        proxy_connect_timeout 60s;
        proxy_read_timeout 315s;
        proxy_send_timeout 5m;
   }
}

server {
    listen x.x.x.2:443 ssl;
    server_name download.domain.com;

    http2 on;

    ssl_certificate /etc/letsencrypt/live/download.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/download.domain.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    resolver 1.1.1.1 8.8.8.8 valid=300s;
    resolver_timeout 5s;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets on; 

    client_header_timeout 5m;
    keepalive_timeout 5m;

   location /api/v1/data/ {
        client_max_body_size 0;
        
        proxy_pass http://unix:/dev/shm/xrxhd.socket;
        
        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_http_version 1.1;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_cache off;
        
        proxy_connect_timeout 60s;
        proxy_read_timeout 315s;
        proxy_send_timeout 5m;
   }
}

Пояснения к настройкам:

  1. Для NGINX настройки аналогичные.

  2. Вместо x.x.x.1 и x.x.x.2 пишем внешние ip адреса вашего сервера. Если вы не привязывали доменные имена, поле server_name опускаете (вообще не пишете).

  3. Сертификаты для доменов или ip адресов предварительно нужно получить самостоятельно у Let's Encript или кого угодно еще.

  4. ssl_ciphers и add_header - не догма, пишите как считаете нужным.

  5. Разделы location должны быть аналогичные для обоих ip адресов, включая путь /api/v1/data/ (любой, но одинаковый. И не забудьте слеш в конце) и файл сокета.

  6. Если не хотите использовать сокет, для общения с XRAY, в proxy_pass можно прописать адрес и порт: 127.0.0.1:4443. Порт может быть любым свободным, он дальше будет использоваться при настройке XRAY.

Создаем входящее подключение для XRAY

Через панель 3x-ui: Входящие - Создать подключение.

Вкладка Основное:

Примечание: все что угодно. Это название подключения.

Протокол: vless

Адрес: /dev/shm/xrxhd.socket,0666. Здесь внимательно. Адрес сокета должен совпадать с адресом сокета в настройках реверсивного прокси. После запятой идут права доступа к файлу сокета, их лучше оставить как в примере. Если в настройках реверс прокси вы указывали 127.0.0.1:4443, то здесь пишем 127.0.0.1

Порт. Если используете сокет, ставите 0 или 1, если 127.0.0.1:4443, ставите 4443 (или какой указали в настройках реверсивного прокси).

Вкладка Поток:

Транспорт - XHTTP.

Путь: /api/v1/data - берем из секции location настроек реверсивного прокси. В этом случае без слеша в конце.

Режим: auto - это важно.

Остальное оставляем как есть.

Вкладка Безопасность: выбираем Нет. За расшифровку SSL у нас отвечает реверсивный прокси.

Вкладка Сниффинг: Включить, выбрать все что есть HTTP, TLS, QUIC, FAKEDNS.

Если выше не упомянуты какие-то поля настроек - оставляем их без изменений.

Дальше добавьте клиента в получившееся входящее подключение (раздел панели Клиенты - Добавить клиентов - Привязанные входящие).

В итоге получаем вот такой шаблон входящего подключения:

{
  "listen": "/dev/shm/xrxhd.socket,0666",
  "port": 1,
  "protocol": "vless",
  "tag": "in-1-tcp",
  "settings": {
    "clients": [
      {
        "id": "xxxxxxxxxxxxxxxx",
        "email": "xxxxx",
        "flow": "",
        "limitIp": 0,
        "totalGB": 0,
        "expiryTime": 0,
        "enable": true,
        "tgId": 0,
        "subId": "xxxxxx",
        "comment": "",
        "reset": 0,
        "created_at": 1756652179000,
        "updated_at": 1782274393000
      }
    ],
    "decryption": "none",
    "encryption": "none"
  },
  "sniffing": {
    "enabled": true,
    "destOverride": [
      "http",
      "tls",
      "quic",
      "fakedns"
    ]
  },
  "streamSettings": {
    "network": "xhttp",
    "xhttpSettings": {
      "path": "/api/v1/data",
      "host": "",
      "mode": "auto",
      "xPaddingBytes": "100-1000",
      "scMaxEachPostBytes": "1000000",
      "scMaxBufferedPosts": 30,
      "scStreamUpServerSecs": "20-80"
    },
    "security": "none"
  }
}

На этом с настройками сервера все. Настройка фаервола, маршрутизации в XRAY и прочие настройки на сервере не относятся к делу, а значит выходят за рамки и без того скучной статьи. ИИ в помощь.

Для чистоты эксперимента проверять делится наш трафик или не делится будем на чистом XRAY без графических клиентов. К сторонним клиентам мы еще вернемся. Как известно, бинарник XRAY одновременно является и клиентом и сервером, поэтому качаем последнюю версию под свою платформу (Windows или Linux роли не играет) прямо с GitHub разработчика. Создаем файл конфигурации для клиента config.json.

Примерно такой
{
  "log": {
    "access": "access.log",
    "error": "error.log",
    "loglevel": "debug",
    "dnsLog": true
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 2080,
      "protocol": "socks",
      "settings": {
        "udp": true
      },
      "tag": "socks-in"
    },
    {
      "listen": "127.0.0.1",
      "port": 2081,
      "protocol": "http",
      "tag": "http-in"
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "upload.domain.com",
            "port": 443,
            "users": [
              {
                "id": "xxxxxxxxxxxxx",
                "security": "auto",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "tag": "vless-out",
      "streamSettings": {
        "network": "xhttp",
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": false,
          "serverName": "upload.domain.com",
          "alpn": [
            "h2",
            "http/1.1"
          ],
          "fingerprint": "firefox"
        },
        "xhttpSettings": {
          "path": "/api/v1/data",
          "host": "upload.domain.com",
          "mode": "auto",
          "xPaddingBytes": "100-1000",
          "downloadSettings": {
            "address": "download.domain.com",
            "port": 443,
            "network": "xhttp",
            "security": "tls",
            "tlsSettings": {
              "serverName": "download.domain.com",
              "alpn": [
                "h2",
                "http/1.1"
              ],
              "fingerprint": "firefox"
            },
            "xhttpSettings": {
              "path": "/api/v1/data",
              "host": "download.domain.com",
              "mode": "auto"
            }
          }
        }
      }
    }
  ]
}

Что важно пояснить в конфигурации.

Во всех секциях, вне “downloadSettings” указываем домен upload.domain.com или ip адрес x.x.x.1 из настроек реверсивного прокси на сервере. Внутри “downloadSettings” соответственно download.domain.com или ip адрес x.x.x.2.

“mode”: “auto” - во всех случаях. Можно в разделе “xhttpSettings”: для исходящего домена upload.domain.com поэкспериментировать с “mode”: “stream-up” или “mode”: “packet-up”, но auto работает точно. “mode”: “stream-one” в нашем случае гарантированно работать не будет. Такова жизнь.

“loglevel”: “debug” - важно указать именно debug, так как нам нужно проверить разделение трафика, а не только ошибки.

Получившийся файл config.json кладем рядом с бинарником XRAY и запускаем из командной строки. Не забудьте сначала в командной строке перейти в папку, где лежит XRAY (cd ... и вот это вот все).

xray --config config.json

Дальше идет описание проверки из под Windows.

Заходим в настройки Windows -> Сеть и Интернет -> Прокси-сервер -> Настройка прокси вручную -> Настройка. Использовать прокси-сервер -> Вкл. IP адрес прокси-сервера 127.0.0.1. Порт 2081 берем из настроек файла клиента (раздел с “protocol”: “http”). Сохраняем, запускаем браузер, открываем 2ip.ru видим ip адрес сервера. Ну или не видим, но чаще видим. Если не видим, проверяем, что сделали не так.

Теперь открываем файл error.log. Он должен появиться в той же папке, что и бинарник XRAY. В этом файле важно найти строки:

transport/internet/splithttp: XHTTP is dialing to tcp:upload.domain.com:443, mode packet-up, HTTP version 2, host upload.domain.com
transport/internet/splithttp: XHTTP is downloading from tcp:download.domain.com:443, mode stream-down, HTTP version 2, host download.domain.com

Должны быть обе строки. Могут идти не подряд, но обязательно должны быть обе. Если в логе есть только первая строка (XHTTP is dialing to tcp ...) - ничего не получилось и весь трафик идет через один ip. Идем в начало статьи, смотрим где накосячили с настройками.

Для тех кто в Linux можно проверить работоспособность нашей поделки через curl. XRAY предварительно должен быть запущен в качестве сервиса или в другом терминале. Номер порта берем из настроек файла клиента (раздел с “protocol”: “socks”).

curl --socks5 127.0.0.1:2080 https://google.com

Дальше, по аналогии с Windows, бежим в логи и ищем две заветные строчки.

Как можно проверить еще, ну вот чтобы вообще на 100%? На примере Windows.

Качаем и запускаем TCPView прямо с сайта Microsoft. В это время у нас уже запущен из командной строки XRAY и включен системный прокси в настройках Windows. В интерфейсе TCPView вверху в поле Search пишем xray, чтобы оставить отображение трафика только одного процеса. Открываем или обновляем в браузере любую страницу. В таблице ниже мы должны увидеть три ip адреса: 127.0.0.1, x.x.x.1 и x.x.x.2. Если видим только два: 127.0.0.1 и x.x.x.1, ничего не работает и день прожит зря. Но, надеюсь, это не про нас.

Что касается графических клиентов для XRAY. Финт с разделением потоков удалось провернуть только на клиенте V2RayN под Windows. Пробовал еще Exclave на Андроиде и Passwall2 на openWRT. В двух последних случаях настройки “downloadSettings” игнорировались и все шло в один поток. Во всех клиентах блок “downloadSettings” я добавлял в раздел "Дополнительные параметры XHTTP (Extra)" в настройках подключения. Просто вставлял блок в соответствующее поле:

"downloadSettings": {
            "address": "download.domain.com",
            "port": 443,
            "network": "xhttp",
            "security": "tls",
            "tlsSettings": {
              "serverName": "download.domain.com",
              "alpn": [
                "h2",
                "http/1.1"
              ],
              "fingerprint": "firefox"
            },
            "xhttpSettings": {
              "path": "/api/v1/data",
              "host": "download.domain.com",
              "mode": "auto"
            }
          }

В случае V2RayN это сработало, Exclave и Passwall2 просто проигнорировали эти настройки, хотя само соединение поднималось. Если у кото-то получится разделить трафик на Андроиде или openWRT, будет очень интересно почитать.

В заключении добавлю, что вся информация предоставлена исключительно в образовательных и научных целях. Ни в коем случае не используйте полученные знания для нарушения закона и доступа к богомерзким запрещенным ресурсам в сети интернет. Да прибудет с Вами сила. Всем бобра.