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

👻 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.

ПараметрЗначенияЧто делает
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-телефонах, пропускается с одним предупреждением в логе. Соединение работает без него.