Skip to content

Shadowsocks — Xray-core

Xray-core supports both classic AEAD-Shadowsocks (AES-GCM, ChaCha20-Poly1305) and Shadowsocks-2022 (2022-blake3-... ciphers) with EIH-based multi-user support. A deprecation banner is printed on load — Xray's developers recommend VLESS encryption as the modern alternative.

Inbound

settings for an inbound of "protocol": "shadowsocks":

FieldTypeDefaultAllowed valuesDescription
methodstring(required)none | plain | aes-128-gcm | aes-256-gcm | chacha20-poly1305 | xchacha20-poly1305 | 2022-blake3-aes-128-gcm | 2022-blake3-aes-256-gcm | 2022-blake3-chacha20-poly1305Cipher / key-derivation scheme. Unknown values map to UNKNOWN at parse time. AEAD aliases (`aead_aes_128_gcm`, etc.) and IETF aliases (`chacha20-ietf-poly1305`) are accepted.
passwordstring(required for single-user, ignored for SS-2022 multi-user)<string> | <base64 key>Single-user password (AEAD) or the **server EIH key** (SS-2022). For SS-2022, the value is base64-encoded raw key bytes whose length matches the cipher (16 / 32 bytes).
levelbyte0<byte>Default policy level when not set per-user.
emailstring(unset)<string>Tag in stats/logs.
users[]*ShadowsocksUserConfig[ShadowsocksUserConfig] | …Inbound account list; same object shape as `clients`. `users` is the newer name introduced in recent Xray and is accepted alongside `clients`.
clients[]*ShadowsocksUserConfig[][ShadowsocksUserConfig]Per-user list. SS-2022 ciphers support multiple users; classic AEAD ciphers do not.
network*NetworkListtcptcp | udp | tcp,udpComma-separated list (or single value) of supported transports.

Source: infra/conf/shadowsocks.go:43-51 · pinned at v26.6.1 (94ffd50)

clients[]

FieldTypeDefaultAllowed valuesDescription
methodstring(inherits server)<see server methods>Per-user cipher (SS-2022 only). Must match the server cipher family.
passwordstring(required)<base64 key>User EIH key. Length must match the cipher (16 or 32 bytes).
levelbyte0<byte>Policy level for this user.
emailstring(unset)<string>User identifier.
address*Address(unset)<host>Optional relay-target address. SS-2022 server-side relay only.
portuint16(unset)<port>Relay-target port (paired with address).

Source: infra/conf/shadowsocks.go:34-41 · pinned at v26.6.1 (94ffd50)

Multi-user is SS-2022 only

The clients[] list only takes effect with one of the 2022-blake3-... ciphers. With a classic AEAD cipher, only the top-level password is honored — extra users in the list are silently ignored.

Outbound

settings for an outbound of "protocol": "shadowsocks":

FieldTypeDefaultAllowed valuesDescription
address*Address(unset)<host>Simplified shape — server hostname or IP.
portuint16(required with address)<port>Server port.
levelbyte0<byte>User level.
emailstring(unset)<string>User identifier.
methodstring(required)<see inbound methods>Cipher used to talk to the server.
passwordstring(required)<string> | <base64 key>Server password / SS-2022 key.
uotboolfalsetrue | falseWrap UDP packets inside the TCP stream (UDP-over-TCP).
uotVersionint21 | 2UoT framing version. Version 2 is the modern default; version 1 exists only for compatibility with the very first sing-box / shadowsocks-2022 clients.
servers[]*ShadowsocksServerTarget(use simplified shape)[ShadowsocksServerTarget]Verbose shape, exactly one entry.

Source: infra/conf/shadowsocks.go:192-202 · pinned at v26.6.1 (94ffd50)

servers[]

FieldTypeDefaultAllowed valuesDescription
address*Address(required)<host>Server hostname or IP.
portuint16(required)<port>Server port.
levelbyte0<byte>User level.
emailstring(unset)<string>User identifier.
methodstring(required)<cipher>Cipher.
passwordstring(required)<string> | <base64 key>Password / SS-2022 key.
uotboolfalsetrue | falseUDP-over-TCP toggle.
uotVersionint21 | 2UoT version.

Source: infra/conf/shadowsocks.go:181-190 · pinned at v26.6.1 (94ffd50)

The outbound accepts either the simplified shape (top-level address, port, method, password) or the verbose servers shape with exactly one entry.

Examples

Classic AEAD inbound:

json
{
  "inbounds": [
    {
      "tag": "ss-in",
      "listen": "0.0.0.0",
      "port": 8388,
      "protocol": "shadowsocks",
      "settings": {
        "method": "aes-256-gcm",
        "password": "<password>",
        "network": "tcp,udp"
      }
    }
  ]
}

SS-2022 inbound with two users:

json
{
  "inbounds": [
    {
      "tag": "ss22-in",
      "listen": "0.0.0.0",
      "port": 8388,
      "protocol": "shadowsocks",
      "settings": {
        "method": "2022-blake3-aes-128-gcm",
        "password": "<base64 16-byte server key>",
        "clients": [
          { "password": "<base64 16-byte alice key>", "email": "alice" },
          { "password": "<base64 16-byte bob key>",   "email": "bob"   }
        ],
        "network": "tcp,udp"
      }
    }
  ]
}

Outbound with UDP-over-TCP:

json
{
  "outbounds": [
    {
      "tag": "ss-out",
      "protocol": "shadowsocks",
      "settings": {
        "address": "example.com",
        "port": 8388,
        "method": "2022-blake3-aes-256-gcm",
        "password": "<base64 32-byte key>",
        "uot": true,
        "uotVersion": 2
      }
    }
  ]
}

Notes

  • The cipher set comes from cipherFromString (infra/conf/shadowsocks.go:16-31) for the classic AEAD family and from shadowaead_2022.List (a vendored upstream constant) for the SS-2022 family. Unknown ciphers return UNKNOWN and fail to build.
  • method: "none" (or "plain") disables encryption entirely — the Shadowsocks framing is preserved but the payload is sent in cleartext. Use only behind another encryption layer.
  • SS-2022 passwords are raw key material, base64-encoded. AEAD-128 ciphers use 16-byte keys; AEAD-256 ciphers use 32-byte keys; ChaCha20 uses 32-byte keys. Wrong-length input fails at protocol-level handshake decoding (not at config parse).
  • uotVersion: 1 is for legacy compatibility only. Use 2 (the default for new configs) unless you need to interoperate with a very early shadowsocks-2022 deployment.
  • The runtime prints a deprecation banner ("Shadowsocks (with no Forward Secrecy, etc.)") at load time — infra/conf/shadowsocks.go:52, 185.

Cross-core notes

  • sing-box uses users[] for SS-2022 multi-user and adds a destinations[] array for the server-side relay form (one SS-2022 server fanning out to multiple upstream addresses). It also supports external plugins (plugin, plugin_opts). See Shadowsocks — sing-box.
  • mihomo uses the field name cipher (not method), takes plugin options as a generic plugin-opts map keyed by the plugin name, and supports a rich set of obfuscation plugins (obfs, v2ray-plugin, shadow-tls, restls, kcptun). See Shadowsocks — mihomo.

Source: infra/conf/shadowsocks.go:34-202 · v26.6.1 (94ffd50)

Core Tutorial by Argsment