Snell — mihomo
Snell is Surge's lightweight proxy protocol. mihomo implements both a Snell outbound (to connect to a Snell server) and, more recently, a Snell inbound listener (to act as one). Both sides support the simple-obfs obfuscation layer with http or tls modes; the outbound's obfs-opts.mode additionally accepts the shadow-tls, restls, and jls TLS-camouflage layers, whose inbound counterparts are the dedicated shadow-tls / res-tls / jls-config listener blocks.
Outbound
Entry under proxies: with type: snell. Embeds BasicOption (common outbound fields).
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
name | string | (required) | <string> | Unique proxy name. |
server | string | (required) | <host> | Upstream server hostname or IP. |
port | int | (required) | <port> | Upstream server port. |
psk | string | (required) | <string> | Pre-shared key (password). |
udp | bool | false | true | false | Enable UDP relaying (Snell v2+). |
version | int | 1 | 1 | 2 | 3 | 4 | 5 | Snell protocol version. v5 servers are backward-compatible with v4 clients, so mihomo dials them as v4. |
reuse | bool | false | true | false | Reuse underlying connections. |
obfs-opts | map[string]any | (disabled) | { mode, ... } | Obfuscation options. `mode` selects `http` / `tls` (simple-obfs, with `host`), or `shadow-tls` / `restls` / `jls`; the remaining keys follow the matching Shadowsocks plugin schema. |
client-fingerprint | string | (global) | chrome | firefox | safari | ios | edge | random | randomized | uTLS client-hello fingerprint used by the `shadow-tls` / `restls` / `jls` obfs modes. |
Source: adapter/outbound/snell.go:32-43 · pinned at v1.19.29 (e26714a)
Inbound
Entry under listeners: with type: snell. Embeds BaseOption (listen, port).
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
psk | string | (required) | <string> | Pre-shared key (password). |
version | int | 4 | 1 | 2 | 3 | 4 | 5 | Snell protocol version. |
udp | bool | false | true | false | Enable UDP relaying (Snell v2+). |
obfs-opts | SnellObfsOption | (disabled) | SnellObfsOption | simple-obfs options (`{ mode, host }`). |
shadow-tls | ShadowTLS | (disabled) | ShadowTLS | Server-side Shadow-TLS camouflage block (`{ enable, version, password, users, handshake, ... }`). |
res-tls | ResTLS | (disabled) | ResTLS | Server-side Restls camouflage block (`{ enable, dest, password, ... }`); unauthenticated clients are relayed to `dest`. |
jls-config | JLSConfig | (disabled) | JLSConfig | Server-side JLS camouflage block (`{ enable, users, sni, dest, ... }`); unauthenticated clients are relayed to `dest`. |
Source: listener/inbound/snell.go:13-22 · pinned at v1.19.29 (e26714a)
obfs-opts
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
mode | string | (unset) | http | tls | Obfuscation mode. |
host | string | (unset) | <host> | Obfuscation host header. |
Source: listener/inbound/snell.go:28-31 · pinned at v1.19.29 (e26714a)
Examples
Outbound — plain Snell:
proxies:
- name: snell-srv
type: snell
server: example.com
port: 44046
psk: <pre-shared-key>
version: 3
udp: trueOutbound — Snell with HTTP obfuscation:
proxies:
- name: snell-obfs
type: snell
server: example.com
port: 44046
psk: <pre-shared-key>
version: 3
obfs-opts:
mode: http
host: bing.comInbound under listeners:
listeners:
- name: snell-in
type: snell
listen: 0.0.0.0
port: 44046
psk: <pre-shared-key>
version: 3
udp: true
obfs-opts:
mode: tls
host: bing.comNotes
pskis the shared secret; the outbound and inbound must use the same value.- UDP relaying requires Snell v2 or newer — enabling
udpon a v1 peer is rejected. reuse(outbound only) reuses the underlying connection. It is implied for Snell v2; for v4 it is opt-in via this field.obfs-opts.modeselects the obfuscation layer:httpwraps the stream in a fake HTTP request,tlsin a fake TLS record (thehostsets the obfuscation host header), andshadow-tls/restls/jlsrun the corresponding TLS-camouflage handshake — the remainingobfs-optskeys then follow the same schema as the matching Shadowsocksplugin-optsblock (see Shadowsocks). Leaveobfs-optsunset for no obfuscation. Both sides must agree on the mode and its settings.- The outbound's
client-fingerprintonly matters for theshadow-tls/restls/jlsobfs modes, where it picks the uTLS client-hello mimicked during the camouflage handshake. - The inbound accepts only
http/tlsinobfs-opts; its TLS-camouflage layers are configured through the dedicatedshadow-tls/res-tls/jls-configblocks instead, which are mutually exclusive.
Cross-core notes
- Snell is Surge-specific. Neither Xray-core nor sing-box supports it — there is no equivalent outbound or inbound in either core.
Source: adapter/outbound/snell.go:32-43 · v1.19.29 (e26714a)
