Перейти к содержимому

Ядро Prizrak-Core

Prizrak-Core — прокси-ядро, на котором работает Prizrak-Box на всех платформах. Оно основано на mihomo (бывший Clash.Meta).

Конфигурации для mihomo работают в Prizrak-Core без изменений. Сверху ядро добавляет возможности, которых нет в mihomo: они описаны ниже.


Prizrak-Core входит в состав Prizrak-Box, но работает и без него. Это самостоятельный бинарник, совместимый с mihomo, поэтому его можно подставить везде, где используется mihomo.

  • Prizrak-Box. Ядро уже встроено, ничего настраивать не нужно.
  • Отдельно. Скачайте архив под свою платформу из релизов и запускайте как обычный mihomo: mihomo -d <папка с config.yaml>. Также можно использовать Docker-образ.
  • TrayClash. Очень лёгкое приложение для Windows, подходит для устройств с Windows 7.
  • OpenWrt-exodus. Инструмент для установки на роутеры: OpenWrt, Asus, Keenetic, MikroTik. Чтобы установилось именно Prizrak-Core, при установке нужно задать специальную переменную. Какую именно — смотрите в документации OpenWrt-exodus.

ВозможностьmihomoPrizrak-Core
Группа smart (выбор узла с ML)—✅
Библиотека uTLSmetacubex/utls v1.8.8prizrak-utls: свежий uTLS, Chrome 155 / Firefox 148 / Safari 26.3
Мультиплексирование mux.cool (Xray Mux, XUDP)—✅ клиент и сервер
REALITY с ML-DSA-65 и синхронизацией с Xray—✅
XHTTP: регулятор потока HTTP/2 (h2-flow)—✅ (выключен по умолчанию)
HTTP/2: буфер отправки 32 КиБ вместо 512 КиБ—✅
freedom: DIRECT с фрагментацией TLS и параметрами сокета (freedom из Xray-core)—✅

Тип группы smart взят из vernesong/mihomo. Группа сама выбирает узел по весам, которые считаются из реальной работы узлов: задержки, доли успешных подключений и трафика. Можно включить предсказание весов моделью LightGBM.

С v1.19.33 группа также узнаёт, куда ведёт каждый узел и какие сайты ему отказывают:

  • Выход узла. Группа определяет страну и сеть (ASN), из которой выходит трафик узла. Для этого она отправляет через узел запрос к cloudflare.com/cdn-cgi/trace, api.ip.sb или ipwho.is: если один не отвечает, используется следующий.
  • Ответы сайтов. Если сайт отказывает узлу (блокировка по региону, страница ошибки, 403, соединение без ответа), группа запоминает это и ведёт этот сайт через другие узлы.
  • Без поспешных выводов. Регион или сеть отмечаются как недоступные, только если отказали несколько независимых узлов из них. Один отказ ничего не решает, а когда узел снова отвечает, запись снимается.

Подробнее о настройке — на странице Прокси группа Smart.


uTLS — библиотека, которая подделывает TLS-отпечаток (ClientHello) под настоящий браузер. От неё зависит, каким браузером выглядит подключение для client-fingerprint и REALITY.

mihomo использует metacubex/utls v1.8.8. Prizrak-Core использует свой форк legiz-ru/prizrak-utls (ветка v1.9.0-mod-meta-mldsa-chr155). Он состоит из трёх частей:

  1. Основа — ветка v1.9.0-mod-meta от metacubex. Это более новая линия, чем v1.8.8 в mihomo, со всеми доработками metacubex.
  2. Свежий апстрим refraction-networking/utls: синхронизация с crypto/tls из Go 1.27.1, отпечаток Chrome 155, исправления распаковки сжатых сертификатов, исправления GREASE и PSK, обмен ключами MLKEM1024. Форк при этом по-прежнему собирается на Go 1.20.
  3. REALITY ML-DSA-65 — см. раздел REALITY.
client-fingerprintmihomoPrizrak-Core
chromeChrome 133Chrome 155
firefoxFirefox 120Firefox 148
safariSafari 16.0Safari 26.3
ios, android, edge, 360, qqбез измененийбез изменений

В Prizrak-Core отпечатки firefox и safari тоже содержат постквантовый обмен ключами X25519MLKEM768, как у настоящих браузеров этих версий. В mihomo он есть только у chrome.


В Prizrak-Core есть мультиплексирование mux.cool, совместимое с Xray. Это тот же протокол, что mux в Xray-core: TCP-потоки и UDP/XUDP-сессии идут поверх общих TCP-соединений. Используется реализация из MetaCubeX/mihomo#2980. Она расширеннее, чем в Xray-core, но полностью с ним совместима.

  • Клиент. Включается у прокси отдельно от smux. Включать их вместе нельзя.
  • Сервер. Входящие VLESS и VMess принимают mux.cool от клиентов Xray.
  • XUDP. Отдельные UDP-сессии с управлением их количеством и политикой для UDP/443.
  • Ограничение соединений. Можно ограничить, сколько TCP-соединений открывается всего, сколько сессий идёт по каждому одновременно и сколько сессий соединение проводит за время жизни. Потом соединение заменяется новым.
proxies:
- name: vless-mux
type: vless
# ...
mux.cool:
enabled: true
# max-carriers: 0 # максимум TCP-соединений, 0 — без ограничения
# max-concurrency: 8 # активных сессий на одно соединение
# max-connections: 128 # сессий за время жизни соединения до ротации
# xudp-concurrency: 4 # отдельных XUDP-сессий на соединение, 0 — общий пул
# xudp-proxy-udp443: reject # reject | allow | skip — что делать с UDP/443

Включить mux.cool для пользователей подписки Remnawave можно через маппер хоста Remnawave, см. раздел Мультиплексирование mux.cool на странице интеграции с Remnawave.


REALITY приведён в соответствие с текущим Xray-core. Используется реализация из MetaCubeX/mihomo#2983.

  • ML-DSA-65. Проверка постквантовой подписи сертификата REALITY, как в Xray. Клиент указывает публичный ключ mldsa65-verify, сервер — mldsa65-seed.
  • ML-KEM, как в Xray. REALITY всегда сохраняет отпечаток выбранного браузера, включая X25519MLKEM768. Опция support-x25519mlkem768 больше не нужна и игнорируется. Для старых серверов укажите явный старый отпечаток, например chrome120.
  • Новые параметры клиента (названия как в Xray):
    • password — синоним public-key;
    • spider-x;
    • show;
    • master-key-log.
  • Новые параметры сервера:
    • target — синоним dest;
    • type;
    • xver;
    • min-client-ver / max-client-ver;
    • mldsa65-seed;
    • show;
    • master-key-log.
proxies:
- name: vless-reality
type: vless
# ...
client-fingerprint: chrome
reality-opts:
public-key: <X25519 public key>
short-id: <short id>
mldsa65-verify: <ML-DSA-65 public key, base64url> # необязательно

Добавить mldsa65-verify для пользователей подписки Remnawave можно через маппер хоста Remnawave, см. раздел REALITY ML-DSA-65 на странице интеграции с Remnawave.


Две доработки по идеям Medium1992 из mihomo-proxy-ros.

Клиентская часть регулятора потока HTTP/2 для XHTTP в режиме h2. Сервер присылает данные с той скоростью, с какой клиент их читает. Без регулятора сервер заполняет большие окна HTTP/2 (в Go это 4 МиБ на поток), и в памяти копятся данные, которые никто не читает. Сервер настраивать не нужно: регулятор работает через стандартное управление потоком HTTP/2 и подходит для любого сервера.

Как он работает:

  • Окно по потреблению. Регулятор показывает серверу окно 64 КиБ, ограничивает размер кадра 16 КиБ и раз в секунду измеряет RTT своим PING. Серверу возвращается кредит, только пока непрочитанных данных меньше, чем клиент успевает прочитать за пару кругов RTT.
  • Быстрый разгон. Новый поток стартует с окном 256 КиБ или с тем, что недавно понадобилось соединению. До первого замера RTT окно открывается на каждый кредит.
  • Модель канала по min_rtt. На Linux и Android регулятор читает из ядра TCP_INFO (rtt, min_rtt, rttvar) и держит окно скачивания не больше 1,25 × максимальная скорость чтения × min_rtt. На других системах используются замеры PING.
  • Совместимость с регулятором на сервере. Такой же регулятор есть на стороне сервера в Jolymmiles/Xray-core (параметр h2Flow). Клиент с регулятором объявляет стандартное окно 65535, по нему сервер понимает, что на другой стороне тоже регулятор, и не ограничивает отправку. Поэтому включать регулятор можно на клиенте, на сервере или на обеих сторонах: скачивание не застопорится, скорость та же.

Выключен по умолчанию, включается в каждом прокси отдельно блоком h2-flow:

xhttp-opts:
h2-flow:
enabled: true
max-stream-receive-window: 16777216 # окно приёма на поток, байт
max-connection-receive-window: 33554432 # окно приёма на соединение, байт
  • enabled включает регулятор.
  • Окна приёма:
    • необязательны, значения от 65535 байт до 1 ГиБ;
    • если не заданы, действуют окна Go по умолчанию (4 МиБ на поток);
    • с регулятором это потолок, а реальное окно следует за чтением;
    • без регулятора это фиксированные окна.
  • h2-flow-control: true тоже работает: это короткая запись h2-flow.enabled: true. Если заданы оба, решает h2-flow.enabled.
  • Скачивание через download-settings использует тот же блок h2-flow.

Работает только в режиме h2. Для h3 и http/1.1 не действует.

Включить h2-flow для пользователей подписки Remnawave можно через маппер хоста Remnawave, см. раздел Регулятор потока XHTTP на странице интеграции с Remnawave.

Долгоживущие HTTP/2-потоки держат буфер отправки открытым всё время соединения. Это XHTTP в режимах stream-one/stream-up и gRPC. Его размер снижен с 512 КиБ до 32 КиБ, через форк legiz-ru/prizrak-http поверх metacubex/http v0.1.8. При большом числе одновременных туннелей это заметно экономит память при той же скорости. Настраивать ничего не нужно.


С v1.19.33-r2 есть тип прокси freedom. Это DIRECT, то есть соединение напрямую с сайтом, плюс параметры fragment и sockopt из исходящего freedom в Xray-core. Два режима фрагментации взяты из sing-box (tls_fragment, tls_record_fragment).

Фрагментация режет TLS ClientHello так, чтобы имя сайта (SNI) никогда не шло одним куском. Это помогает против DPI, который ищет ClientHello целиком. Направляйте в freedom через правила или группы только те сайты, которым это нужно.

proxies:
- name: FRAGMENT
type: freedom
fragment:
packets: tlshello
length: "1-1"
interval: "0"
sockopt:
tcp-congestion: bbr
tcp-keep-alive-idle: 300
tcp-keep-alive-interval: 60
tcp-user-timeout: 10000
custom-sockopt:
- { opt: "1", type: int, value: "1" }
rules:
- DOMAIN-SUFFIX,example.com,FRAGMENT

Это то же самое, что такой исходящий в Xray:

{
"protocol": "freedom",
"settings": { "fragment": { "packets": "tlshello", "length": "1-1", "interval": "0" } },
"streamSettings": {
"sockopt": {
"customSockopt": [{ "opt": "1", "type": "int", "value": "1" }],
"tcpcongestion": "bbr",
"tcpKeepAliveIdle": 300,
"tcpKeepAliveInterval": 60,
"tcpUserTimeout": 10000
}
},
"tag": "FRAGMENT"
}

Обычные параметры DIRECT тоже работают: interface-name, routing-mark, ip-version, tfo, mptcp. UDP идёт так же, как через DIRECT.

ПараметрЗначенияЧто делает
packetstlshello, "N-M" или пустоtlshello переписывает первый ClientHello в несколько TLS-записей. "1-3" режет первые три отправки соединения на TCP-сегменты, пусто — режет все отправки
length"N" или "N-M", байтРазмер куска. Обязателен при split: length
interval"N" или "N-M", мсПауза между кусками. При tlshello и 0 все записи уходят одной отправкой
max-split"N" или "N-M"Не больше стольких кусков, последний забирает остаток. Пусто или 0 — без ограничения
splitlength (по умолчанию) или snisni: по одному случайному разрезу внутри каждой части имени сайта, кроме домена верхнего уровня, как в sing-box; length тогда не нужен
waitinterval (по умолчанию) или ackack: каждый кусок уходит отдельным TCP-сегментом, а следующий ждёт подтверждения от сервера, как в sing-box
fallback-delayмс, по умолчанию 500Пауза для wait: ack, если подтверждение узнать нельзя
  • Диапазоны работают как в Xray: верхняя граница не входит, "100-200" даёт от 100 до 199.
  • Большой ClientHello (с постквантовыми ключами) часто приходит в нескольких отправках. freedom копит его, пока запись не придёт целиком, и только потом режет. Xray в этом случае отправляет его без нарезки.
  • После нарезанной части соединение работает на полной скорости: данные снова копируются между сокетами напрямую.
  • При wait: ack подтверждение читается на Linux, Android, macOS и iOS. На Windows и других системах используется fallback-delay. Подтверждение быстрее 20 мс считается ответом промежуточного узла, а не сервера, и тогда тоже ждётся fallback-delay. Для близких серверов уменьшите его, иначе каждый кусок обойдётся в 500 мс.
ПараметрЗначенияЧто делает
tcp-congestionbbr, cubic, …Алгоритм управления перегрузкой TCP. Только Linux и Android
tcp-user-timeoutмсСколько отправленные данные могут оставаться без подтверждения, прежде чем соединение закроется. Только Linux и Android
tcp-keep-alive-idleсекундыПростой до первой проверки keep-alive. Отрицательное значение выключает keep-alive
tcp-keep-alive-intervalсекундыИнтервал между проверками keep-alive
custom-sockoptсписокЛюбой параметр сокета, как customSockopt в Xray

Поля custom-sockopt:

  • opt: номер параметра;
  • value: его значение;
  • type: int (по умолчанию) или str;
  • level: по умолчанию 6 (TCP);
  • system: linux, windows, darwin или пусто для всех систем; linux действует и на Android;
  • network: tcp, tcp4, tcp6 или пусто.

Числа можно писать в десятичном виде или как 0x…. На Windows работают только значения int.

Параметр, который система или ядро ОС не поддерживает, например bbr на многих Android-телефонах, пропускается с одним предупреждением в логе. Соединение работает без него.