Snell — mihomo
Snell is Surge's lightweight proxy protocol. mihomo implements both a Snell outbound (to connect to a Snell server) and 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.31 (ab405ba)
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.31 (ab405ba)
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.31 (ab405ba)
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 originated in Surge. Xray-core does not support it. sing-box implements Snell inbounds and outbounds (
type: "snell"; outboundversion4 or 6, inbound 5 or 6 — Snell v5's QUIC proxy mode is intentionally not implemented), with snake_case fields such aspsk,obfs_modeandobfs_host. See Snell — sing-box.
Source: adapter/outbound/snell.go:32-43 · v1.19.31 (ab405ba)
