# sbp `sbp` 在用户级别安装和管理 sing-box 代理服务. 不需要 root. 服务由 systemd user 管理. 它提供六个协议, 一个命令行接口, 和一个全屏 TUI. ## 安装 一条命令安装 `sbp` 命令: ```bash 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` 搭建服务. 也可以让安装脚本直接搭建: ```bash 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. ## 快速开始 ```bash 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` 选择子集: ```bash sbp install --protocols hysteria2,vless-reality ``` 每个协议使用独立端口. 默认从 `20000` 开始分配空闲端口. 用 `--base-port` 改变起点. REALITY 需要一个域名作为握手目标. 默认使用 `--sni` 的值. 如果 `--sni` 是 IP, REALITY 会拒绝启动. 请显式指定域名: ```bash sbp install --sni www.example.com ``` ## 命令行 ### 安装与升级 ```bash 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 # 同时删除配置和证书 ``` ### 协议 ```bash 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 ``` ### 用户 ```bash 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` 后运行: ```bash sing-box run -c client.json ``` 客户端配置包含 `127.0.0.1:1080` 的 mixed 入站. 它同时提供 SOCKS5 和 HTTP 代理. ### Clash / mihomo `--clash` 输出可合并的 `proxies:` 块: ```bash 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 或更高版本. ### 服务与设置 ```bash 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 ```bash 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`. 自签名证书适合个人使用. 如果需要兼容更多客户端, 使用已有证书: ```bash 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` 注册. ## 测试 ```bash 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`.