Sudoku — mihomo
Sudoku is a mihomo-native obfuscating proxy protocol. It carries an AEAD-encrypted record stream whose bytes are mapped onto sudoku-grid-style lookup tables, so the wire image can be biased toward printable ASCII or high-entropy noise. On top of that it offers optional HTTP(S) masking, randomized record padding, stream multiplexing, and UDP-over-TCP. mihomo ships it as both an outbound (client) and an inbound (listener).
Outbound
Entry under proxies: with type: sudoku. Embeds BasicOption (common outbound fields such as tfo, mptcp, interface-name, routing-mark, ip-version, dialer-proxy).
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
name | string | (required) | <string> | Unique proxy name. |
server | string | (required) | <host> | Server hostname or IP. |
port | int | (required) | 1-65535 | Server port. |
key | string | (required) | <string> | Pre-shared key. Must match the server; the AEAD seed and obfuscation tables are derived from it. |
aead-method | string | chacha20-poly1305 | <aead cipher> | AEAD cipher protecting the record layer. |
padding-min | *int | 10 | <int> | Lower bound (bytes) of the random padding added to records. |
padding-max | *int | 30 | <int> | Upper bound (bytes) of the random padding added to records. |
table-type | string | prefer_entropy | prefer_ascii | prefer_entropy | up_ascii_down_entropy | up_entropy_down_ascii | Obfuscation byte-table orientation. The directional forms let the uplink and downlink use different tables. |
enable-pure-downlink | *bool | true | true | false | Use the lighter pure-downlink framing on the server-to-client direction. |
http-mask | *bool | true | true | false | Wrap the connection in an HTTP(S) tunnel so it looks like ordinary web traffic. Enabled by default. |
http-mask-mode | string | legacy | legacy | stream | poll | auto | ws | HTTP masking transport. legacy is the classic upgrade; stream / poll / auto use real HTTP request/response tunnels; ws is a WebSocket tunnel. |
http-mask-tls | bool | false | true | false | Wrap the HTTP tunnel in TLS. Only applies to the stream / poll / auto modes. |
http-mask-host | string | (unset) | <domain[:port]> | Host / SNI override sent on the masking tunnel. |
path-root | string | (unset) | <path> | First-level path prefix for the HTTP tunnel endpoints. |
http-mask-multiplex | string | off | off | auto | on | Tunnel reuse. auto reuses an h1/h2 tunnel; on opens a single multiplexed tunnel carrying multiple targets. |
httpmask | *SudokuHTTPMaskOptions | (unset) | <object> | Structured HTTP-mask block; its keys override the flat http-mask-* fields above. |
custom-table | string | (unset) | <layout> | Custom byte-layout pattern (e.g. xpxvvpvv) instead of a built-in table. |
custom-tables | []string | (unset) | [<layout>] | Rotation of custom byte-layout patterns. Overrides custom-table when non-empty. |
Source: adapter/outbound/sudoku.go:30-50 · pinned at v1.19.27 (5184081)
httpmask
A structured alternative to the flat http-mask-* fields. When present, its keys take precedence.
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
disable | bool | false | true | false | Disable HTTP masking for this proxy. |
mode | string | legacy | legacy | stream | poll | auto | ws | HTTP masking transport (same values as http-mask-mode). |
tls | bool | false | true | false | Wrap the tunnel in TLS (stream / poll / auto only). |
host | string | (unset) | <domain[:port]> | Host / SNI override. |
path-root | string | (unset) | <path> | First-level path prefix for tunnel endpoints. |
multiplex | string | off | off | auto | on | Tunnel reuse (same values as http-mask-multiplex). |
Source: adapter/outbound/sudoku.go:52-59 · pinned at v1.19.27 (5184081)
Inbound
Entry under listeners: with type: sudoku. Embeds BaseOption (common listener fields: name, listen, port, …).
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
key | string | (required) | <string> | Pre-shared key. Clients must present the same value. |
aead-method | string | chacha20-poly1305 | <aead cipher> | AEAD cipher protecting the record layer. |
padding-min | *int | 10 | <int> | Lower bound (bytes) of random record padding. |
padding-max | *int | 30 | <int> | Upper bound (bytes) of random record padding. |
table-type | string | prefer_entropy | prefer_ascii | prefer_entropy | up_ascii_down_entropy | up_entropy_down_ascii | Obfuscation byte-table orientation; must be compatible with the client. |
handshake-timeout | *int | 5 | <seconds> | Maximum time allowed to complete the handshake before the connection is dropped. |
enable-pure-downlink | *bool | true | true | false | Use the lighter pure-downlink framing on the server-to-client direction. |
custom-table | string | (unset) | <layout> | Custom byte-layout pattern (e.g. xpxvvpvv). |
custom-tables | []string | (unset) | [<layout>] | Rotation of custom byte-layout patterns. Overrides custom-table when non-empty. |
disable-http-mask | bool | false | true | false | Turn off the HTTP masking layer on the listener. |
http-mask-mode | string | legacy | legacy | stream | poll | auto | HTTP masking transport accepted from clients. |
path-root | string | (unset) | <path> | First-level path prefix for the HTTP tunnel endpoints. |
fallback | string | (unset) | <host:port> | Where to forward connections that fail the Sudoku handshake — point it at a decoy site for camouflage. |
httpmask | *SudokuHTTPMaskOptions | (unset) | <object> | Structured HTTP-mask block; its keys override disable-http-mask / http-mask-mode / path-root. |
mux-option | MuxOption | (unset) | <object> | Multiplex settings (mihomo extension, not part of the standard Sudoku protocol). |
Source: listener/inbound/sudoku.go:14-33 · pinned at v1.19.27 (5184081)
httpmask
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
disable | bool | false | true | false | Disable HTTP masking on the listener. |
mode | string | legacy | legacy | stream | poll | auto | HTTP masking transport (same values as http-mask-mode). |
path-root | string | (unset) | <path> | First-level path prefix for tunnel endpoints. |
Source: listener/inbound/sudoku.go:35-39 · pinned at v1.19.27 (5184081)
Examples
Minimal client outbound:
proxies:
- name: sudoku-out
type: sudoku
server: example.com
port: 443
key: "your-pre-shared-key"HTTP-masked over TLS, with multiplex reuse:
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: autoDirectional table with wider padding:
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: 64Server-side listener with a camouflage 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:8080Notes
keyis mandatory and must be identical on both ends — both the AEAD seed and the obfuscation tables are derived from it.table-typechooses how record bytes are shaped:prefer_asciibiases toward printable text,prefer_entropy(the default) toward random noise, and theup_*_down_*forms apply different tables per direction.http-mask(on by default) wraps the stream so it resembles HTTP(S) traffic.http-mask-tlsonly matters for thestream/poll/automodes;wsruns a WebSocket tunnel (client side only).http-mask-multiplex: oncarries multiple targets over a single multiplexed tunnel;autoreuses an existing h1/h2 tunnel when possible.custom-table/custom-tablesare advanced knobs for the byte layout;custom-tablesrotates through several patterns and overridescustom-tablewhen set.- Sudoku relays UDP via UDP-over-TCP, so it works for UDP-based traffic without a separate transport.
- On the listener,
fallbackforwards connections that fail the Sudoku handshake to another address — typically a decoy web server, so probes see an innocuous site.
Cross-core notes
- Sudoku is mihomo-only. Neither sing-box nor Xray-core implements it; reach for their own obfuscation transports (e.g. Shadowsocks plugins) if you need a comparable disguise there.
Source: adapter/outbound/sudoku.go:30-50 · v1.19.27 (5184081)
Source: listener/inbound/sudoku.go:14-33 · v1.19.27 (5184081)
