👻 freedom: фрагментация TLS и параметры сокета
С 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.
fragment
Заголовок раздела «fragment»| Параметр | Значения | Что делает |
|---|---|---|
packets | tlshello, "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 — без ограничения |
split | length (по умолчанию) или sni | sni: по одному случайному разрезу внутри каждой части имени сайта, кроме домена верхнего уровня, как в sing-box; length тогда не нужен |
wait | interval (по умолчанию) или ack | ack: каждый кусок уходит отдельным 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 мс.
sockopt
Заголовок раздела «sockopt»| Параметр | Значения | Что делает |
|---|---|---|
tcp-congestion | bbr, 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-телефонах, пропускается с одним предупреждением в логе. Соединение работает без него.