Skip to content

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

ПолеТипПо умолчаниюДопустимые значенияОписание
namestring(required)<string>Уникальное имя прокси.
serverstring(required)<host>Имя хоста или IP сервера.
portint(required)1-65535Порт сервера.
keystring(required)<string>Предварительно разделённый ключ. Должен совпадать с серверным; из него выводятся seed для AEAD и таблицы обфускации.
aead-methodstringchacha20-poly1305<aead cipher>AEAD-шифр, защищающий уровень записей.
padding-min*int10<int>Нижняя граница (в байтах) случайного заполнения, добавляемого к записям.
padding-max*int30<int>Верхняя граница (в байтах) случайного заполнения, добавляемого к записям.
table-typestringprefer_entropyprefer_ascii | prefer_entropy | up_ascii_down_entropy | up_entropy_down_asciiОриентация байтовых таблиц обфускации. Направленные варианты позволяют использовать разные таблицы для восходящего и нисходящего направлений.
enable-pure-downlink*booltruetrue | falseИспользовать облегчённое кадрирование pure-downlink в направлении от сервера к клиенту.
http-mask*booltruetrue | falseОбернуть соединение в HTTP(S)-туннель, чтобы оно выглядело как обычный веб-трафик. Включено по умолчанию.
http-mask-modestringlegacylegacy | stream | poll | auto | wsТранспорт HTTP-маскировки. legacy — классический upgrade; stream / poll / auto используют настоящие туннели из HTTP-запросов/ответов; ws — WebSocket-туннель.
http-mask-tlsboolfalsetrue | falseОбернуть HTTP-туннель в TLS. Действует только в режимах stream / poll / auto.
http-mask-hoststring(unset)<domain[:port]>Переопределение Host / SNI, отправляемое в маскирующем туннеле.
path-rootstring(unset)<path>Префикс пути первого уровня для конечных точек HTTP-туннеля.
multiplexstringoffoff | auto | onМультиплексирование потоков. `auto` переиспользует туннель h1/h2; `on` запускает мультиплексирование сессии поверх чистого TCP или HTTP-маски.
http-mask-multiplexstring(unset)off | auto | onУстаревший плоский псевдоним `multiplex`; если задан, имеет приоритет.
httpmask*SudokuHTTPMaskOptions(unset)<object>Структурированный блок HTTP-маски; его ключи переопределяют плоские поля http-mask-* выше.
custom-tablestring(unset)<layout>Пользовательский шаблон байтовой раскладки (например, xpxvvpvv) вместо встроенной таблицы.
custom-tables[]string(unset)[<layout>]Ротация пользовательских шаблонов байтовой раскладки. Непустое значение переопределяет custom-table.

Исходный код: adapter/outbound/sudoku.go:29-50 · зафиксировано на v1.19.29 (e26714a)

httpmask

Структурированная альтернатива плоским полям http-mask-*. Если блок присутствует, его ключи имеют приоритет.

ПолеТипПо умолчаниюДопустимые значенияОписание
disableboolfalsetrue | falseОтключить HTTP-маскировку для этого прокси.
modestringlegacylegacy | stream | poll | auto | wsТранспорт HTTP-маскировки (те же значения, что у http-mask-mode).
tlsboolfalsetrue | falseОбернуть туннель в TLS (только stream / poll / auto).
hoststring(unset)<domain[:port]>Переопределение Host / SNI.
path-rootstring(unset)<path>Префикс пути первого уровня для конечных точек туннеля.
multiplexstringoffoff | auto | onПереиспользование туннеля (те же значения, что у http-mask-multiplex).

Исходный код: adapter/outbound/sudoku.go:52-59 · зафиксировано на v1.19.29 (e26714a)

Входящий

Запись в listeners: с type: sudoku. Встраивает BaseOption (общие поля слушателей: name, listen, port, …).

ПолеТипПо умолчаниюДопустимые значенияОписание
keystring(required)<string>Предварительно разделённый ключ. Клиенты должны предъявлять то же значение.
aead-methodstringchacha20-poly1305<aead cipher>AEAD-шифр, защищающий уровень записей.
padding-min*int10<int>Нижняя граница (в байтах) случайного заполнения записей.
padding-max*int30<int>Верхняя граница (в байтах) случайного заполнения записей.
table-typestringprefer_entropyprefer_ascii | prefer_entropy | up_ascii_down_entropy | up_entropy_down_asciiОриентация байтовых таблиц обфускации; должна быть совместима с клиентом.
handshake-timeout*int5<seconds>Максимальное время на завершение рукопожатия, по истечении которого соединение разрывается.
enable-pure-downlink*booltruetrue | falseИспользовать облегчённое кадрирование pure-downlink в направлении от сервера к клиенту.
custom-tablestring(unset)<layout>Пользовательский шаблон байтовой раскладки (например, xpxvvpvv).
custom-tables[]string(unset)[<layout>]Ротация пользовательских шаблонов байтовой раскладки. Непустое значение переопределяет custom-table.
disable-http-maskboolfalsetrue | falseОтключить слой HTTP-маскировки на слушателе.
http-mask-modestringlegacylegacy | stream | poll | autoТранспорт HTTP-маскировки, принимаемый от клиентов.
path-rootstring(unset)<path>Префикс пути первого уровня для конечных точек HTTP-туннеля.
fallbackstring(unset)<host:port>Куда перенаправлять соединения, не прошедшие рукопожатие Sudoku, — укажите сайт-приманку для камуфляжа.
httpmask*SudokuHTTPMaskOptions(unset)<object>Структурированный блок HTTP-маски; его ключи переопределяют disable-http-mask / http-mask-mode / path-root.
mux-optionMuxOption(unset)<object>Настройки мультиплексирования (расширение mihomo, не входит в стандартный протокол Sudoku).

Исходный код: listener/inbound/sudoku.go:14-33 · зафиксировано на v1.19.29 (e26714a)

httpmask

ПолеТипПо умолчаниюДопустимые значенияОписание
disableboolfalsetrue | falseОтключить HTTP-маскировку на слушателе.
modestringlegacylegacy | stream | poll | autoТранспорт HTTP-маскировки (те же значения, что у http-mask-mode).
path-rootstring(unset)<path>Префикс пути первого уровня для конечных точек туннеля.

Исходный код: listener/inbound/sudoku.go:35-39 · зафиксировано на v1.19.29 (e26714a)

Примеры

Минимальный клиентский исходящий:

yaml
proxies:
  - name: sudoku-out
    type: sudoku
    server: example.com
    port: 443
    key: "your-pre-shared-key"

HTTP-маскировка поверх TLS с переиспользованием через мультиплексирование:

yaml
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

Направленная таблица с более широким заполнением:

yaml
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:

yaml
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)

Core Tutorial от Argsment