Shadowsocks 部署指南(sing-box)

Shadowsocks 2022 版(2022-blake3-*)修复了旧版协议的重放攻击漏洞,建议只使用 2022 系列加密方法。协议自带加密,无 TLS 层,无需证书。需要 sing-box 1.14.0 及以上(与本系列其他篇一致;2022 方法本身更早可用)。字段说明见 Shadowsocks inbound

一、部署前准备

  • 一台使用 systemd 的 Linux VPS,具备 root 或 sudo 权限;官方安装脚本覆盖 deb / rpm / Arch / OpenWrt
  • 云安全组和本机防火墙都放行 TCP 443,且未被其他程序占用;服务端默认同时监听 TCP 和 UDP,需要 UDP 转发时一并放行——只改安全组不够;
  • 一个符合加密方法要求的密钥(见第三章)。

二、安装 sing-box

bash
curl -fsSL https://sing-box.app/install.sh | sh
sing-box version

输出中的版本号必须 ≥ 1.14.0。若要钉死版本:

bash
curl -fsSL https://sing-box.app/install.sh | sh -s -- --version 1.14.0

脚本会下载 sing-box、安装 systemd 服务(以 sing-box 用户运行)并创建 /etc/sing-box/

三、选择加密方法并生成密钥

1. 加密方法选择

加密方法 密钥长度 说明
2022-blake3-aes-128-gcm 16 字节 AES-128,主流选择,CPU 支持 AES 加速时性能最好
2022-blake3-aes-256-gcm 32 字节 AES-256,安全性余量更大
2022-blake3-chacha20-poly1305 32 字节 无 AES 硬件加速的设备(部分 ARM)上性能更好;不支持多用户(EIH)

2. 生成密钥

2022 系列要求密钥为恰好对应长度的 Base64 字符串,直接用 sing-box 生成:

bash
# 16 字节(对应 aes-128-gcm)
sing-box generate rand --base64 16

# 32 字节(对应 aes-256-gcm 或 chacha20-poly1305)
sing-box generate rand --base64 32

也可以用 OpenSSL 生成:

bash
openssl rand -base64 16

密钥必须与客户端完全一致,且长度必须精确匹配所选加密方法,否则服务端无法启动或连接失败。

四、写入服务端配置

将以下配置写入 /etc/sing-box/config.json

json
{
  "log": {
    "level": "info",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "shadowsocks",
      "listen": "::",
      "listen_port": 443,
      "method": "2022-blake3-aes-128-gcm",
      "password": "CHANGE_THIS_TO_GENERATED_KEY"
    }
  ],
  "outbounds": [
    {
      "type": "direct"
    }
  ]
}

必须修改的字段

配置项 说明
password 替换为生成的密钥,长度必须匹配加密方法
method 与客户端一致的加密方法,默认示例为 2022-blake3-aes-128-gcm
listen_port 服务端监听端口,默认 443
listen 默认 ::(IPv6 + IPv4)。机器禁用 IPv6 时改为 0.0.0.0

可选字段说明

  • network:省略时同时监听 TCP 与 UDP,一般无需设置。只保留 TCP 时设为 "tcp",只保留 UDP 时设为 "udp"。官方字段是二者之一,不要"tcp,udp",也不要写成数组 ["tcp", "udp"]——要双栈就删掉该字段;
  • multiplex:多路复用;padding: true 启用填充、增加流量特征随机性,两端需配置一致(示例见下)。

可选:启用多路复用(示例)

服务端入站与客户端出站加入相同配置:

json
"multiplex": {
  "enabled": true,
  "padding": true
}

开启 padding 后服务端会拒绝未填充的连接。

设置配置文件权限(官方服务以 sing-box 用户运行,600、属主 root 即可):

bash
sudo chmod 600 /etc/sing-box/config.json

五、检查并启动

bash
sudo sing-box check -c /etc/sing-box/config.json
sudo systemctl enable sing-box
sudo systemctl restart sing-box
sudo systemctl status sing-box --no-pager

check 没有输出且退出码为 0 表示配置通过。status 应为 active (running);否则查看日志:

bash
sudo journalctl -u sing-box --output cat -e

六、服务管理

操作 命令
查看状态 sudo systemctl status sing-box --no-pager
启动 sudo systemctl start sing-box
停止 sudo systemctl stop sing-box
重启 sudo systemctl restart sing-box
禁用开机自启 sudo systemctl disable sing-box
查看最近日志 sudo journalctl -u sing-box --output cat -e
实时查看日志 sudo journalctl -u sing-box --output cat -f

七、客户端配置参考

下面是一份可直接 sing-box check 的最小客户端配置:本地 mixed 入站 + 一个出站。出站必须放在 outbounds 数组里,不能把出站对象单独当成完整配置文件。

json
{
  "log": {
    "level": "info",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "mixed",
      "listen": "127.0.0.1",
      "listen_port": 1080
    }
  ],
  "outbounds": [
    {
      "type": "shadowsocks",
      "tag": "ss-out",
      "server": "YOUR_SERVER_IP",
      "server_port": 443,
      "method": "2022-blake3-aes-128-gcm",
      "password": "CHANGE_THIS_TO_GENERATED_KEY"
    }
  ]
}

本机 SOCKS / HTTP 代理为 127.0.0.1:1080

要点:

客户端字段 说明
server VPS 公网 IP
server_port 与服务端 listen_port 一致
method 与服务端 method 完全一致
password 与服务端 password 完全一致

Shadowsocks 无 TLS 层,客户端不配置 tls 段。开在 443 能过防火墙,但流量不像 HTTPS。客户端出站默认同时支持 TCP 与 UDP(network 留空即两者);若只走 TCP,设为 "tcp"。UDP 能否实际使用由服务端 network 与防火墙共同决定。启用服务端 multiplex 时,客户端需配置一致的 multiplex 段。

八、多用户配置(可选)

单端口多用户使用 users 数组:顶层 password 是服务端密钥(必填,不要删除),users 中为每个用户的独立密钥:

json
{
  "inbounds": [
    {
      "type": "shadowsocks",
      "listen": "::",
      "listen_port": 443,
      "method": "2022-blake3-aes-128-gcm",
      "password": "SERVER_KEY",
      "users": [
        {
          "name": "user1",
          "password": "USER1_KEY"
        },
        {
          "name": "user2",
          "password": "USER2_KEY"
        }
      ]
    }
  ]
}

name 仅用于日志标识,可以省略;顶层 password 与每个 users[].password 都按所选方法生成(如 sing-box generate rand --base64 16)。

对应用户的客户端出站 password 需要把两段密钥用冒号拼起来——服务端密钥在前、用户密钥在后:

json
"password": "SERVER_KEY:USER_KEY"

EIH 多用户仅支持 2022-blake3-aes-128-gcm2022-blake3-aes-256-gcm 两种方法;2022-blake3-chacha20-poly1305 不支持多用户。

中转链场景(流量经另一台 Shadowsocks 服务器转发)需要链式拼接多层 iPSK(参考 SIP023 规范),配置较复杂,本文不展开;普通自用场景用上面的多用户即可。

九、故障排查

1. 服务启动失败

bash
sudo sing-box check -c /etc/sing-box/config.json
sudo journalctl -u sing-box -n 100 --no-pager

重点排查:

  • password 长度是否与加密方法匹配(aes-128-gcm 对应 16 字节 Base64,其余对应 32 字节);
  • password 是否为合法 Base64 字符串;
  • 使用多用户时顶层 password(服务端密钥)是否缺失——多用户模式下它仍是必填项;
  • network 是否写成了 "tcp,udp" 或数组;
  • 端口是否被占用(TCP 与 UDP 都看:sudo ss -lntup | grep ':443');
  • 禁用 IPv6 的机器是否仍在听 ::(改为 0.0.0.0)。

2. 客户端无法连接

依次确认:

  1. systemctl statusactive (running)
  2. 云安全组和系统防火墙放行对应端口(服务端默认同时监听 TCP 与 UDP,需要 UDP 时记得放行);
  3. 客户端 method 与服务端一致;单用户时 password 与服务端完全一致,多用户时 password服务端密钥:用户密钥 形式(顺序、冒号均不能错);
  4. 客户端密钥长度与服务端相同(两侧必须使用同一套密钥,不是各生成各的);
  5. multiplex 两侧配置一致;
  6. 服务端日志中没有认证失败或解密错误。

3. 日志频繁出现认证失败

少量失败通常来自互联网扫描,属正常现象。持续大量失败时检查:

  • 客户端密钥是否与 password 完全一致(注意 Base64 大小写和结尾 =);
  • 密钥是否已泄露,泄露后立即更换。

十、安全建议

  • 只使用 2022 系列加密方法;旧版(aes-256-gcm 等非 2022 前缀)存在已知重放攻击风险;
  • 密钥用生成命令出,长度必须匹配加密方法;泄露后立即更换;
  • config.json 权限 600
  • 443 上无 TLS,被主动探测时特征与 HTTPS 不同;
  • 定期升级 sing-box,升级后重新执行 sing-box check