Sudoku — mihomo
Sudoku — собственный обфусцирующий прокси-протокол mihomo. Он несёт AEAD-зашифрованный поток записей, байты которого отображаются через таблицы подстановки в духе судоку, поэтому картину трафика на проводе можно сместить в сторону печатаемого ASCII либо высокоэнтропийного шума. Поверх этого он предлагает опциональную HTTP(S)-маскировку, случайное заполнение записей, мультиплексирование потоков и UDP-over-TCP. mihomo поставляет его и как исходящий (клиент), и как входящий (слушатель).
Исходящий
Запись в proxies: с type: sudoku. Встраивает BasicOption (общие поля исходящих, такие как tfo, mptcp, interface-name, routing-mark, ip-version, dialer-proxy).
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
name | string | (required) | <string> | Уникальное имя прокси. |
server | string | (required) | <host> | Имя хоста или IP сервера. |
port | int | (required) | 1-65535 | Порт сервера. |
key | string | (required) | <string> | Предварительно разделённый ключ. Должен совпадать с серверным; из него выводятся seed для AEAD и таблицы обфускации. |
aead-method | string | chacha20-poly1305 | <aead cipher> | AEAD-шифр, защищающий уровень записей. |
padding-min | *int | 10 | <int> | Нижняя граница (в байтах) случайного заполнения, добавляемого к записям. |
padding-max | *int | 30 | <int> | Верхняя граница (в байтах) случайного заполнения, добавляемого к записям. |
table-type | string | prefer_entropy | prefer_ascii | prefer_entropy | up_ascii_down_entropy | up_entropy_down_ascii | Ориентация байтовых таблиц обфускации. Направленные варианты позволяют использовать разные таблицы для восходящего и нисходящего направлений. |
enable-pure-downlink | *bool | true | true | false | Использовать облегчённое кадрирование pure-downlink в направлении от сервера к клиенту. |
http-mask | *bool | true | true | false | Обернуть соединение в HTTP(S)-туннель, чтобы оно выглядело как обычный веб-трафик. Включено по умолчанию. |
http-mask-mode | string | legacy | legacy | stream | poll | auto | ws | Транспорт HTTP-маскировки. legacy — классический upgrade; stream / poll / auto используют настоящие туннели из HTTP-запросов/ответов; ws — WebSocket-туннель. |
http-mask-tls | bool | false | true | false | Обернуть HTTP-туннель в TLS. Действует только в режимах stream / poll / auto. |
http-mask-host | string | (unset) | <domain[:port]> | Переопределение Host / SNI, отправляемое в маскирующем туннеле. |
path-root | string | (unset) | <path> | Префикс пути первого уровня для конечных точек HTTP-туннеля. |
multiplex | string | off | off | auto | on | Мультиплексирование потоков. `auto` переиспользует туннель h1/h2; `on` запускает мультиплексирование сессии поверх чистого TCP или HTTP-маски. |
http-mask-multiplex | string | (unset) | off | auto | on | Устаревший плоский псевдоним `multiplex`; если задан, имеет приоритет. |
httpmask | *SudokuHTTPMaskOptions | (unset) | <object> | Структурированный блок HTTP-маски; его ключи переопределяют плоские поля http-mask-* выше. |
custom-table | string | (unset) | <layout> | Пользовательский шаблон байтовой раскладки (например, xpxvvpvv) вместо встроенной таблицы. |
custom-tables | []string | (unset) | [<layout>] | Ротация пользовательских шаблонов байтовой раскладки. Непустое значение переопределяет custom-table. |
Исходный код: adapter/outbound/sudoku.go:29-50 · зафиксировано на v1.19.29 (e26714a)
httpmask
Структурированная альтернатива плоским полям http-mask-*. Если блок присутствует, его ключи имеют приоритет.
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
disable | bool | false | true | false | Отключить HTTP-маскировку для этого прокси. |
mode | string | legacy | legacy | stream | poll | auto | ws | Транспорт HTTP-маскировки (те же значения, что у http-mask-mode). |
tls | bool | false | true | false | Обернуть туннель в TLS (только stream / poll / auto). |
host | string | (unset) | <domain[:port]> | Переопределение Host / SNI. |
path-root | string | (unset) | <path> | Префикс пути первого уровня для конечных точек туннеля. |
multiplex | string | off | off | auto | on | Переиспользование туннеля (те же значения, что у http-mask-multiplex). |
Исходный код: adapter/outbound/sudoku.go:52-59 · зафиксировано на v1.19.29 (e26714a)
Входящий
Запись в listeners: с type: sudoku. Встраивает BaseOption (общие поля слушателей: name, listen, port, …).
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
key | string | (required) | <string> | Предварительно разделённый ключ. Клиенты должны предъявлять то же значение. |
aead-method | string | chacha20-poly1305 | <aead cipher> | AEAD-шифр, защищающий уровень записей. |
padding-min | *int | 10 | <int> | Нижняя граница (в байтах) случайного заполнения записей. |
padding-max | *int | 30 | <int> | Верхняя граница (в байтах) случайного заполнения записей. |
table-type | string | prefer_entropy | prefer_ascii | prefer_entropy | up_ascii_down_entropy | up_entropy_down_ascii | Ориентация байтовых таблиц обфускации; должна быть совместима с клиентом. |
handshake-timeout | *int | 5 | <seconds> | Максимальное время на завершение рукопожатия, по истечении которого соединение разрывается. |
enable-pure-downlink | *bool | true | true | false | Использовать облегчённое кадрирование pure-downlink в направлении от сервера к клиенту. |
custom-table | string | (unset) | <layout> | Пользовательский шаблон байтовой раскладки (например, xpxvvpvv). |
custom-tables | []string | (unset) | [<layout>] | Ротация пользовательских шаблонов байтовой раскладки. Непустое значение переопределяет custom-table. |
disable-http-mask | bool | false | true | false | Отключить слой HTTP-маскировки на слушателе. |
http-mask-mode | string | legacy | legacy | stream | poll | auto | Транспорт HTTP-маскировки, принимаемый от клиентов. |
path-root | string | (unset) | <path> | Префикс пути первого уровня для конечных точек HTTP-туннеля. |
fallback | string | (unset) | <host:port> | Куда перенаправлять соединения, не прошедшие рукопожатие Sudoku, — укажите сайт-приманку для камуфляжа. |
httpmask | *SudokuHTTPMaskOptions | (unset) | <object> | Структурированный блок HTTP-маски; его ключи переопределяют disable-http-mask / http-mask-mode / path-root. |
mux-option | MuxOption | (unset) | <object> | Настройки мультиплексирования (расширение mihomo, не входит в стандартный протокол Sudoku). |
Исходный код: listener/inbound/sudoku.go:14-33 · зафиксировано на v1.19.29 (e26714a)
httpmask
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
disable | bool | false | true | false | Отключить HTTP-маскировку на слушателе. |
mode | string | legacy | legacy | stream | poll | auto | Транспорт HTTP-маскировки (те же значения, что у http-mask-mode). |
path-root | string | (unset) | <path> | Префикс пути первого уровня для конечных точек туннеля. |
Исходный код: listener/inbound/sudoku.go:35-39 · зафиксировано на v1.19.29 (e26714a)
Примеры
Минимальный клиентский исходящий:
proxies:
- name: sudoku-out
type: sudoku
server: example.com
port: 443
key: "your-pre-shared-key"HTTP-маскировка поверх TLS с переиспользованием через мультиплексирование:
proxies:
- name: sudoku-tls
type: sudoku
server: example.com
port: 443
key: "your-pre-shared-key"
http-mask-mode: stream
http-mask-tls: true
http-mask-host: www.example.com
path-root: /assets
http-mask-multiplex: autoНаправленная таблица с более широким заполнением:
proxies:
- name: sudoku-tuned
type: sudoku
server: 192.0.2.10
port: 8443
key: "your-pre-shared-key"
table-type: up_ascii_down_entropy
padding-min: 16
padding-max: 64Серверный слушатель с камуфляжным fallback:
listeners:
- name: sudoku-in
type: sudoku
listen: 0.0.0.0
port: 443
key: "your-pre-shared-key"
http-mask-mode: stream
fallback: 127.0.0.1:8080Примечания
keyобязателен и должен совпадать на обеих сторонах — из него выводятся и seed для AEAD, и таблицы обфускации.table-typeопределяет, как оформляются байты записей:prefer_asciiсмещает их к печатаемому тексту,prefer_entropy(по умолчанию) — к случайному шуму, а вариантыup_*_down_*применяют для каждого направления свою таблицу.http-mask(включён по умолчанию) оборачивает поток так, что он напоминает HTTP(S)-трафик.http-mask-tlsимеет значение только для режимовstream/poll/auto;wsзапускает WebSocket-туннель (только на стороне клиента).multiplex: onнесёт несколько целей по одной мультиплексированной сессии (поверх чистого TCP или HTTP-маски);autoпо возможности переиспользует существующий туннель h1/h2.http-mask-multiplex— устаревший плоский псевдоним, переопределяющийmultiplex, если задан;httpmask.multiplexпереопределяет оба.custom-table/custom-tables— продвинутые ручки байтовой раскладки;custom-tablesперебирает несколько шаблонов по кругу и, если задан, переопределяетcustom-table.- Sudoku ретранслирует UDP через UDP-over-TCP, поэтому работает с UDP-трафиком без отдельного транспорта.
- На слушателе
fallbackперенаправляет соединения, не прошедшие рукопожатие Sudoku, на другой адрес — обычно на веб-сервер-приманку, чтобы зондирующие видели безобидный сайт.
Сравнение с другими ядрами
- Sudoku есть только в mihomo. Ни sing-box, ни Xray-core его не реализуют; если там нужна сопоставимая маскировка, используйте их собственные обфусцирующие транспорты (например, плагины Shadowsocks).
Исходный код: adapter/outbound/sudoku.go:29-50 · v1.19.29 (e26714a)
Исходный код: listener/inbound/sudoku.go:14-33 · v1.19.29 (e26714a)
