Files
sbp/README.md
T

7.0 KiB

sbp

sbp 在用户级别安装和管理 sing-box 代理服务. 不需要 root. 服务由 systemd user 管理. 它提供六个协议, 一个命令行接口, 和一个全屏 TUI.

安装

一条命令安装 sbp 命令:

curl -fsSL https://gitea.typist.cc/typist/sbp/raw/branch/main/install.sh | bash
sbp

install.sh 把程序放到 ~/.local/share/sbp/app, 并建立 ~/.local/bin/sbp 符号链接. 环境变量 SBP_BIN 改变命令目录. SBP_APP_DIR 改变程序目录.

安装后运行 sbp install 搭建服务. 也可以让安装脚本直接搭建:

curl -fsSL https://gitea.typist.cc/typist/sbp/raw/branch/main/install.sh | bash -s -- --run

依赖: Linux, systemd user, openssl, python3 3.9 或更高版本, curl. 网络必须能访问 GitHub.

快速开始

sbp install                 # 安装全部六个协议, 自动分配端口, 生成用户 u1
sbp                         # 打开 TUI
sbp status                  # 查看状态
sbp user show u1            # 打印 u1 的全部分享链接

协议

协议 传输 证书 说明
Hysteria2 UDP 需要 默认开启 salamander 混淆
VLESS + REALITY TCP 不需要 借用真实网站的 TLS 握手
Trojan TCP 需要 经典 TLS 代理
Shadowsocks 2022 TCP 不需要 每个用户独立密钥
TUIC v5 UDP 需要 QUIC 传输
AnyTLS TCP 需要 使用填充方案

默认安装全部协议. 用 --protocols 选择子集:

sbp install --protocols hysteria2,vless-reality

每个协议使用独立端口. 默认从 20000 开始分配空闲端口. 用 --base-port 改变起点.

REALITY 需要一个域名作为握手目标. 默认使用 --sni 的值. 如果 --sni 是 IP, REALITY 会拒绝启动. 请显式指定域名:

sbp install --sni www.example.com

命令行

安装与升级

sbp install --host 203.0.113.10 --sni www.example.com
sbp install --cert fullchain.pem --key privkey.pem --sni example.com
sbp install --protocols hysteria2,trojan --base-port 30000
sbp upgrade                 # 升级 sing-box
sbp uninstall               # 删除服务和程序, 保留配置
sbp uninstall --purge       # 同时删除配置和证书

协议

sbp protocol list
sbp protocol enable tuic --port 24000
sbp protocol disable tuic
sbp protocol port tuic 24001
sbp protocol set hysteria2 obfs false
sbp protocol set vless-reality short_id 0123456789abcdef

用户

sbp user list
sbp user add phone
sbp user del phone
sbp user show phone
sbp user show phone --protocol hysteria2 --uri
sbp user show phone --protocol hysteria2 --json

--json 输出完整的 sing-box 客户端配置. 客户端保存为 client.json 后运行:

sing-box run -c client.json

客户端配置包含 127.0.0.1:1080 的 mixed 入站. 它同时提供 SOCKS5 和 HTTP 代理.

Clash / mihomo

--clash 输出可合并的 proxies: 块:

sbp user show phone --clash
sbp user show phone --protocol trojan --clash

把输出粘贴到 clash.yaml 的 proxies: 下, 再在 proxy-groups 里引用节点名. 自签证书时, hysteria2 用 fingerprint 固定证书, 其余协议用 skip-cert-verify: true. anytls 需要 mihomo v1.19.3 或更高版本.

服务与设置

sbp service start|stop|restart
sbp service logs -n 200
sbp settings host 203.0.113.10
sbp settings sni www.example.com
sbp settings cert --cert fullchain.pem --key privkey.pem --sni example.com
sbp cert show
sbp cert renew

TUI

sbp tui

TUI 提供这些页面:

  • Dashboard: 状态总览, 启动, 停止, 重启.
  • Protocols: 启用, 停用, 改端口, 改选项.
  • Users: 增加, 删除, 查看分享链接, Clash 配置和客户端配置.
  • Settings: 修改 host 和 SNI, 更换证书, 升级, 重装, 卸载.
  • Logs: 查看 journal.

操作键: ↑/↓ 或 j/k 移动, Enter 确认, q 返回.

证书

默认生成自签名 ECDSA P-256 证书, 有效期 10 年. 客户端配置使用 certificate_public_key_sha256 固定证书公钥. 分享链接使用 pinSHA256 或 allowInsecure=1.

自签名证书适合个人使用. 如果需要兼容更多客户端, 使用已有证书:

sbp settings cert --cert fullchain.pem --key privkey.pem --sni example.com

文件位置

路径 内容
~/.config/sbp/state.json 用户, 协议, 端口, 密钥
~/.config/sbp/sing-box.json 生成的 sing-box 服务端配置
~/.config/sbp/certs/ 证书和私钥
~/.local/share/sbp/bin/sing-box sing-box 程序
~/.local/share/sbp/app/ sbp 程序文件
~/.config/systemd/user/sbp.service systemd user 单元

路径遵循 XDG_CONFIG_HOME 和 XDG_DATA_HOME.

安全设计

  • 密码, UUID, Shadowsocks 密钥由 secrets 或 os.urandom 生成, 每个用户独立.
  • 默认自签名 ECDSA P-256 证书, 只含一个 SAN.
  • TLS 最低版本 1.3, Hysteria2 和 TUIC 只用 h3 ALPN.
  • 客户端配置固定证书公钥. 不开启 insecure.
  • 服务以非特权用户运行, 只监听 >= 1024 的端口.
  • 下载的 sing-box 压缩包与 GitHub 发布的 sha256 摘要比对.
  • 新版本 sing-box 必须通过当前配置的 check, 才会替换旧程序.
  • systemd 加固: NoNewPrivileges, ProtectSystem=strict, ProtectHome=read-only, PrivateTmp, PrivateDevices, ProtectProc=invisible, ProtectKernelTunables, MemoryDenyWriteExecute, SystemCallFilter=@system-service, 空 capability 集.
  • InaccessiblePaths 屏蔽家目录中的常见凭据目录.
  • 配置和状态文件权限 0600, 证书目录权限 0700.
  • 日志级别 warn, 不记录访问日志.

代码结构

src/sbp/
  cli.py              命令行入口和参数解析
  commands/           每个命令组一个模块
  state.py            状态模型, JSON 读写, 迁移
  config.py           生成 sing-box 服务端和客户端配置
  share.py            生成分享链接和 Clash 节点
  clash.py            Clash (mihomo) YAML 输出
  protocols/          每个协议一个模块
  ops/                业务操作, CLI 和 TUI 共用
  tui/                curses 界面

协议模块只做四件事: 生成 inbound, 分享链接, 客户端 outbound, Clash 节点. 它不读写文件, 不操作服务, 不访问网络. 新增协议只需要在 protocols/ 增加一个模块, 并在 protocols/__init__.py 注册.

测试

PYTHONPATH=src:. python3 -m unittest discover -s tests

测试覆盖状态迁移, 配置生成, 分享链接, 端口分配, 以及安装流程. 测试不访问网络, 也不依赖已安装的 sing-box.

说明

  • 主机需要公网可达的端口. 路由器 NAT 需要端口转发.
  • 防火墙需要放行协议端口. UDP 协议放行 UDP, TCP 协议放行 TCP.
  • 用户级服务依赖 lingering. 确认 loginctl show-user $USER -p Linger 输出 Linger=yes. sbp install 在未开启 lingering 时给出警告.
  • 主机没有 IPv6 时, 默认监听 0.0.0.0.
  • Python 的 urllib 不读取 ALL_PROXY. 使用 SOCKS 代理时请设置 HTTPS_PROXY.