完善使用说明

This commit is contained in:
CN-JS-HuiBai
2026-04-15 20:00:47 +08:00
parent 21b5338817
commit 565a788f77
8 changed files with 593 additions and 22 deletions

435
README.md
View File

@@ -1,34 +1,435 @@
> Sponsored by [Warp](https://go.warp.dev/sing-box), built for coding with multiple AI agents
> Sponsored by CodeX
<a href="https://go.warp.dev/sing-box">
<img alt="Warp sponsorship" width="400" src="https://github.com/warpdotdev/brand-assets/raw/refs/heads/main/Github/Sponsor/Warp-Github-LG-02.png">
</a>
# sing-box Xboard Fork
---
这是一个基于上游 [SagerNet/sing-box](https://github.com/SagerNet/sing-box) 的定制分支,主要面向 Xboard / UniProxy 面板联动部署场景。
# sing-box
它保留了上游 `sing-box` 内核能力,同时补充了:
The universal proxy platform.
- Xboard 动态入站服务
- 多节点托管
- 面板协议自动识别
- VLESS / REALITY 面板字段映射
- Shadowsocks 2022 用户同步与密钥处理
- AnyTLS / Trojan / Hysteria / TUIC 的本地 TLS / ACME 支持
- 安装脚本与分离式配置模板
- PROXY protocol 客户端真实 IP 传递
## Repository Notice
如果你要查看官方功能基线、通用配置文档、原始内核行为,请优先参考上游:
This repository is a customized fork based on the upstream [SagerNet/sing-box](https://github.com/SagerNet/sing-box) project.
- 上游仓库:https://github.com/SagerNet/sing-box
- 上游文档https://sing-box.sagernet.org
- Upstream project: `sing-box`
- Upstream documentation: https://sing-box.sagernet.org
- This repository may contain local modifications for Xboard integration, deployment scripts, and protocol handling behavior
## 适用场景
If you are looking for the official project, feature baseline, or upstream release notes, please refer to the upstream `sing-box` repository first.
这个仓库更适合以下用途:
[![Packaging status](https://repology.org/badge/vertical-allrepos/sing-box.svg)](https://repology.org/project/sing-box/versions)
- 从 Xboard / UniProxy 面板拉取节点配置
- 从面板拉取用户并动态更新
- 单机运行多个节点
- 给面板型机场节点准备安装脚本
- 对接面板下发的 `protocol``cert_config``accept_proxy_protocol`、REALITY 字段等
## Documentation
## 主要特性
https://sing-box.sagernet.org
- `services.xboard` 动态服务
- 支持单节点和多节点
- 协议优先从面板返回的 `protocol` 识别
- 支持面板回包控制 `accept_proxy_protocol`
- 支持 VLESS REALITY 的 `server_name``public_key``private_key``short_id`
- 支持 ACME
- `auto_tls`
- `cert_mode = http`
- `cert_mode = dns`
- 当前已支持的 ACME DNS provider
- `cloudflare`
- `alidns`
- `tencentcloud`
- `dnspod`
- `acmedns`
- 安装脚本默认生成:
- `/etc/sing-box/config.d/10-base.json`
- `/etc/sing-box/config.d/20-outbounds.json`
- 安装后的服务名为:
- `singbox.service`
## 仓库内关键文件
- [install.sh](./install.sh)
Linux 安装脚本
- [option/xboard.go](./option/xboard.go)
`services.xboard` 配置结构
- [service/xboard/service.go](./service/xboard/service.go)
Xboard 动态服务实现
- [configs](./configs)
配置示例目录
## 快速开始
### 1. 编译并安装
在 Linux 服务器上进入仓库目录:
```bash
chmod +x install.sh
./install.sh
```
脚本会做这些事情:
1. 检查 Go 环境
2. 编译当前仓库代码
3. 生成分离配置
4. 创建 `singbox.service`
5. 启动服务
### 2. 安装过程会询问的内容
- `Panel URL`
- `Panel Token`
- 一个或多个 `Node ID`
- DNS 模式:
- `udp`
- `local`
- 当前节点前面是否有发送 PROXY protocol 的四层代理
### 3. 多节点输入规则
- 安装脚本会持续要求输入 `Node ID`
- 输入 `NO` 才结束
- 至少要有一个节点
## 运行与管理
查看状态:
```bash
systemctl status singbox
```
查看日志:
```bash
journalctl -u singbox -f
```
重启服务:
```bash
systemctl restart singbox
```
手动运行:
```bash
sing-box -D /var/lib/sing-box -C /etc/sing-box/config.d run
```
## 推荐配置结构
建议把配置拆成两部分。
### `10-base.json`
放这些内容:
- 日志
- DNS
- `services`
- 基础路由规则
### `20-outbounds.json`
放这些内容:
- 全部出站
- 出站标签
- 你自己的分流依赖
这样更方便:
- 面板动态服务和你的自定义出站分离
- 安装脚本生成的基础配置不容易被误改
- 调整出站时不会影响 Xboard 服务主体
示例已放在:
- [configs/10-base.single-node.json](./configs/10-base.single-node.json)
- [configs/10-base.multi-node.json](./configs/10-base.multi-node.json)
- [configs/20-outbounds.example.json](./configs/20-outbounds.example.json)
## `services.xboard` 配置说明
配置结构定义见 [option/xboard.go](./option/xboard.go)。
### 最小单节点示例
```json
{
"type": "xboard",
"panel_url": "https://panel.example.com",
"key": "replace-with-node-token",
"sync_interval": "1m",
"report_interval": "1m",
"node_id": 286
}
```
### 多节点示例
```json
{
"type": "xboard",
"panel_url": "https://panel.example.com",
"key": "replace-with-node-token",
"sync_interval": "1m",
"report_interval": "1m",
"nodes": [
{
"node_id": 286
},
{
"node_id": 774
}
]
}
```
### 当前推荐做法
- 只传 `panel_url`
- 只传 `key`
- 只传 `node_id``nodes`
下面这些字段仍然保留兼容,但常规部署一般不需要:
- `config_panel_url`
- `user_panel_url`
- `config_node_id`
- `user_node_id`
- `node_type`
说明:
- 当前逻辑会优先从面板回包中的 `protocol` 自动识别协议
- `node_type` 更适合做历史兼容,不建议再依赖它做主配置
## 面板配置回包约定
### 1. 协议识别
推荐面板显式返回:
```json
{
"protocol": "vless"
}
```
当前服务会按如下顺序识别协议:
1. `protocol`
2. `node_type`
3. 如果是 Shadowsocks 且存在 `cipher`,则回退识别为 `shadowsocks`
### 2. 监听地址与端口
推荐面板返回:
```json
{
"listen_ip": "0.0.0.0",
"server_port": 443
}
```
### 3. PROXY protocol
如果前面有四层代理,并且它会发送 PROXY protocol 头,需要面板返回:
```json
{
"accept_proxy_protocol": true
}
```
如果用户是直连节点,不要开启这个字段,否则连接会失败。
### 4. VLESS REALITY
当前支持从面板获取这些字段:
- `tls_settings.server_name`
- `tls_settings.public_key`
- `tls_settings.private_key`
- `tls_settings.short_id`
- 顶层 `server_name`
- 顶层 `public_key`
- 顶层 `private_key`
- 顶层 `short_id`
示例见:
- [configs/panel-response.vless-reality.json](./configs/panel-response.vless-reality.json)
### 5. Shadowsocks 2022
推荐面板返回:
- `protocol: "shadowsocks"`
- `cipher`
- `server_key`
示例见:
- [configs/panel-response.shadowsocks2022.json](./configs/panel-response.shadowsocks2022.json)
### 6. AnyTLS / Trojan / Hysteria / TUIC 的证书要求
这些协议通常要求本地具备可用 TLS 证书。当前支持:
- 文件证书
- 证书内容直传
- ACME 自动签发
如果面板没有下发可用证书,也没有有效 ACME 配置,常见报错是:
```text
Xboard setup error: missing certificate
```
示例见:
- [configs/panel-response.anytls-acme-dns.json](./configs/panel-response.anytls-acme-dns.json)
## ACME 说明
当前支持:
- `auto_tls: true`
- `cert_mode: "http"`
- `cert_mode: "dns"`
### DNS-01 provider
已支持:
- `cloudflare`
- `alidns`
- `tencentcloud`
- `dnspod`
- `acmedns`
### DNSPod 说明
仓库已经内置 DNSPod provider 适配,不再依赖旧版 `github.com/libdns/dnspod` 的接口兼容。
你可以从面板下发:
```json
{
"cert_config": {
"cert_mode": "dns",
"dns_provider": "dnspod",
"dns_env": {
"DNSPOD_TOKEN": "id,token"
}
}
}
```
也可以下发腾讯云凭据:
```json
{
"cert_config": {
"cert_mode": "dns",
"dns_provider": "tencentcloud",
"dns_env": {
"TENCENTCLOUD_SECRET_ID": "xxx",
"TENCENTCLOUD_SECRET_KEY": "xxx"
}
}
}
```
## 配置示例目录
[configs](./configs) 目录中已经提供了这些示例:
- [configs/10-base.single-node.json](./configs/10-base.single-node.json)
单节点基础配置
- [configs/10-base.multi-node.json](./configs/10-base.multi-node.json)
多节点基础配置
- [configs/20-outbounds.example.json](./configs/20-outbounds.example.json)
出站配置模板
- [configs/panel-response.vless-reality.json](./configs/panel-response.vless-reality.json)
VLESS REALITY 面板回包
- [configs/panel-response.shadowsocks2022.json](./configs/panel-response.shadowsocks2022.json)
Shadowsocks 2022 面板回包
- [configs/panel-response.anytls-acme-dns.json](./configs/panel-response.anytls-acme-dns.json)
AnyTLS + ACME DNS 验证面板回包
## 常见问题
### `unsupported protocol: empty`
原因通常是:
- 面板没有返回 `protocol`
- 兼容字段 `node_type` 也为空
建议:
- 面板显式返回顶层 `protocol`
### `Xboard setup error: missing certificate`
原因通常是:
- AnyTLS / Trojan / Hysteria / TUIC 需要证书
- 面板没有下发证书文件、证书内容或 ACME 参数
### `TLS handshake: REALITY: processed invalid connection`
多数情况下表示客户端参数和当前 REALITY 节点配置不匹配,例如:
- `server_name` 错误
- `public_key` 错误
- `short_id` 错误
- 客户端实际上不是按 REALITY 模式连入
### `Server does not exist`
通常是:
- 面板里不存在该 `node_id`
- `token` 不匹配
- 拉取配置或拉取用户的节点 ID 写错
### 真实 IP 没有正确获取
请确认:
1. 前置代理确实发送了 PROXY protocol
2. 面板确实下发了 `accept_proxy_protocol: true`
否则服务只能看到上游代理 IP。
## 开发验证
近期已验证通过的命令:
```bash
go test ./common/dnspod ./common/tls ./service/acme ./service/xboard
go build -trimpath -tags 'with_quic,with_utls,with_clash_api,with_gvisor,with_acme' ./cmd/sing-box
```
如果你改动了 Xboard、协议映射、ACME 或证书相关逻辑,建议至少执行一次以上命令。
## License
```
```text
Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu>
This program is free software: you can redistribute it and/or modify

View File

@@ -0,0 +1,50 @@
{
"log": {
"level": "info",
"timestamp": true
},
"experimental": {
"cache_file": {
"enabled": true,
"path": "/var/lib/sing-box/cache.db"
}
},
"dns": {
"servers": [
{
"tag": "dns-local",
"type": "local"
}
]
},
"services": [
{
"type": "xboard",
"panel_url": "https://panel.example.com",
"key": "replace-with-node-token",
"sync_interval": "1m",
"report_interval": "1m",
"nodes": [
{
"node_id": 286
},
{
"node_id": 774
},
{
"node_id": 815
}
]
}
],
"inbounds": [],
"route": {
"rules": [
{
"protocol": "dns",
"action": "hijack-dns"
}
],
"auto_detect_interface": true
}
}

View File

@@ -0,0 +1,42 @@
{
"log": {
"level": "info",
"timestamp": true
},
"experimental": {
"cache_file": {
"enabled": true,
"path": "/var/lib/sing-box/cache.db"
}
},
"dns": {
"servers": [
{
"tag": "dns-upstream",
"type": "udp",
"server": "1.1.1.1",
"server_port": 53
}
]
},
"services": [
{
"type": "xboard",
"panel_url": "https://panel.example.com",
"key": "replace-with-node-token",
"sync_interval": "1m",
"report_interval": "1m",
"node_id": 286
}
],
"inbounds": [],
"route": {
"rules": [
{
"protocol": "dns",
"action": "hijack-dns"
}
],
"auto_detect_interface": true
}
}

View File

@@ -0,0 +1,12 @@
{
"outbounds": [
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
}
]
}

View File

@@ -0,0 +1,33 @@
{
"protocol": "anytls",
"listen_ip": "0.0.0.0",
"server_port": 45365,
"network": null,
"networkSettings": null,
"server_name": "code.example.com",
"accept_proxy_protocol": false,
"padding_scheme": [
"stop=8",
"0=30-30",
"1=100-400",
"2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000",
"3=9-9,500-1000",
"4=500-1000",
"5=500-1000",
"6=500-1000",
"7=500-1000"
],
"cert_config": {
"cert_mode": "dns",
"domain": "code.example.com",
"dns_provider": "tencentcloud",
"dns_env": {
"TENCENTCLOUD_SECRET_ID": "replace-with-secret-id",
"TENCENTCLOUD_SECRET_KEY": "replace-with-secret-key"
}
},
"base_config": {
"push_interval": 60,
"pull_interval": 60
}
}

View File

@@ -0,0 +1,16 @@
{
"protocol": "shadowsocks",
"listen_ip": "0.0.0.0",
"server_port": 30009,
"network": null,
"networkSettings": null,
"cipher": "2022-blake3-aes-256-gcm",
"plugin": null,
"plugin_opts": null,
"server_key": "NjQzMWVlNjVmYTkwODk0OTMyOTg3MzZmYzczMmFlMTI=",
"accept_proxy_protocol": false,
"base_config": {
"push_interval": 60,
"pull_interval": 60
}
}

View File

@@ -0,0 +1,21 @@
{
"protocol": "vless",
"listen_ip": "0.0.0.0",
"server_port": 18443,
"network": "tcp",
"tls": 2,
"flow": "xtls-rprx-vision",
"accept_proxy_protocol": false,
"tls_settings": {
"server_name": "git.example.com",
"server_port": "443",
"public_key": "replace-with-client-visible-public-key",
"private_key": "replace-with-server-private-key",
"short_id": "0123456789abcdef",
"allow_insecure": false
},
"base_config": {
"push_interval": 60,
"pull_interval": 60
}
}

View File

@@ -95,10 +95,6 @@ build_sing_box() {
echo -e "${RED}Failed to download Go modules.${NC}"
exit 1
fi
if ! go get github.com/libdns/dnspod@v0.0.3 github.com/libdns/tencentcloud@v1.4.3; then
echo -e "${RED}Failed to download ACME DNS provider modules.${NC}"
exit 1
fi
if ! go mod tidy; then
echo -e "${RED}Failed to refresh Go module metadata.${NC}"
exit 1