前言

sing-box 以“简洁、强大、灵活”为核心理念,支持多种协议(如 VLESS、VMess、Trojan、Shadowsocks、HTTP、SOCKS 等),并提供 DNS 增强、规则路由、透明代理、TUN 模式等高级功能。其配置采用清晰的 JSON 格式,易于理解与维护;同时支持 Windows、macOS、Linux、Android、iOS 等主流操作系统,真正实现“一套配置,全平台通行”。

我们这里就以在基于alpine的lxc容器搭建sing-box服务端为示例。

pve创建lxc容器

首先,我们需要一个干净的 Alpine Linux 容器。

  1. 在 PVE Web 界面中,创建一个新的LXC容器。
  2. 模板: 选择最新的 alpine-....-default 模板。
  3. 资源:
    • 磁盘: 1 GB 就绰绰有余。
    • CPU: 1 核心。
    • 内存: 128 MB 或 256 MB 即可。
  4. 网络: 静态IPv4,192.168.x.x/24;IPv6选择SLAAC
  5. 创建并启动容器。

安装sing-box

更新,安装工具

1
2
3
4
5
# 更新软件包源
apk update

# 安装基础工具
apk add curl vim

sing-box

1
2
3
4
5
6
7
8
9
10
11
12
# 下载 Sing-box 压缩包 (请将下面的链接替换为GitHub上最新的版本)
curl -Lo sing-box.tar.gz "https://github.com/SagerNet/sing-box/releases/download/v1.9.0-alpha.16/sing-box-1.9.0-alpha.16-linux-amd64.tar.gz"

# 解压缩
tar -xzf sing-box.tar.gz

# 从解压出的文件夹中找到 sing-box 主程序,并移动到系统可执行路径
# 文件夹名会随着版本变化,用通配符 * 来查找
mv sing-box-*/sing-box /usr/local/bin/

# 授予执行权限
chmod +x /usr/local/bin/sing-box

配置文件

1
2
mkdir -p /etc/sing-box/
vim /etc/sing-box/config.json

配置文件示例:

wireguard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"endpoints": [
//wireguard
{
"type": "wireguard",
"tag": "wg-in",
"listen_port": 51820,
"private_key": "服务端私钥",
"address": [
"10.0.0.1/24"
],
"peers": [
{
"public_key": "第一个客户端公钥",
"allowed_ips": [
"10.0.0.2/32"
],
"persistent_keepalive_interval": 25 // 保持连接,防止NAT超时
},
{
"public_key": "第二个客户端公钥",
"allowed_ips": [
"10.0.0.3/32"
],
"persistent_keepalive_interval": 25 // 保持连接,防止NAT超时
}
]
}
}

hysteria2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"inbounds": [
//hysteria2节点
{
"type": "hysteria2",
"tag": "hysteria2-in",
"listen": "::",
"listen_port": 443,
"bind_interface": "eth0",
"users": [
{
"password": "ddsadwadasa"
}
],
"tls": {
"enabled": true,
"certificate_path": "/etc/nginx/ssl/.crt",
"key_path": "/etc/nginx/ssl/.key"
},
"masquerade": "https://www.bing.com"
}
],
}

tuic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"inbounds": [
{
"type": "tuic",
"tag": "tuic-in",
"listen": "::",
"listen_port": 80,
"users": [
{
"name": "demo",
"uuid": "",
"password": ""
}
],
"congestion_control": "bbr",
"auth_timeout": "3s",
"heartbeat": "10s",
"zero_rtt_handshake": false,
"tls": {
"enabled": true,
"alpn": "h3",
"server_name": "",
"certificate_path": "/etc/nginx/ssl/.crt",
"key_path": "/etc/nginx/ssl/.key"
}
},
],
}

vless

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"inbounds": [
//vless节点
{
"type": "vless",
"tag": "vless-in",
"listen": "127.0.0.1",
"listen_port": 80,
"users": [
{
"uuid": "dsadwsafasadwad",
"flow": ""
}
],
"transport": {
"type": "ws",
"path": "/dw321d1sd"
}
}
],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
{
"log": {
"level": "info",
"timestamp": true
},
"endpoints": [
//wireguard
{
"type": "wireguard",
"tag": "wg-in",
"listen_port": 51820,
"private_key": "服务端私钥",
"address": [
"10.0.0.1/24"
],
"peers": [
{
"public_key": "第一个客户端公钥",
"allowed_ips": [
"10.0.0.2/32"
],
"persistent_keepalive_interval": 25 // 保持连接,防止NAT超时
},
{
"public_key": "第二个客户端公钥",
"allowed_ips": [
"10.0.0.3/32"
],
"persistent_keepalive_interval": 25 // 保持连接,防止NAT超时
}
]
}
]
"inbounds": [
//vless节点
{
"type": "vless",
"tag": "vless-in",
"listen": "127.0.0.1",
"listen_port": 80,
"users": [
{
"uuid": "dsadwsafasadwad",
"flow": ""
}
],
"transport": {
"type": "ws",
"path": "/dw321d1sd"
}
},
//hysteria2节点
{
"type": "hysteria2",
"tag": "hysteria2-in",
"listen": "::",
"listen_port": 443,
"bind_interface": "eth0",
"users": [
{
"password": "ddsadwadasa"
}
],
"tls": {
"enabled": true,
"certificate_path": "/etc/nginx/ssl/.crt",
"key_path": "/etc/nginx/ssl/.key"
},
"masquerade": "https://www.bing.com"
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
},
{
"type": "http",
"tag": "netease-proxy-out",
"server": "192.168.1.101",
"server_port": 8081
},
{
"type": "socks",
"tag": "mihomo-proxy-out",
"server": "192.168.1.101",
"server_port": 7891,
"version": "5"
}
],
"route": {
"rules": [
// 规则1: 只要是 vless-in 进来的流量,全部直连
{
"inbound": "vless-in",
"outbound": "direct-out"
},
// 规则2: 如果是 hysteria2-in 进来的,并且目标是网易云音乐的域名,则走网易云解锁出口
{
"inbound": "hysteria2-in",
"domain": [
"music.163.com", "apm.music.163.com","apm3.music.163.com",
"interface.music.163.com", "interface3.music.163.com",
"interface.music.163.com.163jiasu.com", "interface3.music.163.com.163jiasu.com"
],
"outbound": "netease-proxy-out"
},
// 规则3: 捕获所有剩下的 hysteria2-in 流量,全部发往SOCKS出口
{
"inbound": "hysteria2-in",
"outbound": "mihomo-proxy-out"
}
]
}
}

创建 OpenRC 服务 (Alpine的服务管理)

这是 Alpine 与 Debian/Ubuntu 最大的不同之处。Alpine 使用 OpenRC 而不是 systemd

  1. 创建 OpenRC 服务脚本文件:

    1
    vim /etc/init.d/sing-box
  2. 将以下脚本内容完整地粘贴进去:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #!/sbin/openrc-run
    #
    # openrc service script for sing-box
    #

    # Sing-box可执行文件的路径
    command="/usr/local/bin/sing-box"
    # 运行参数,-c 指定配置文件路径
    command_args="run -c /etc/sing-box/config.json"
    # 以root用户运行
    command_user="root"

    # PID文件的位置,用于服务管理
    pidfile="/run/${RC_SVCNAME}.pid"
    # 告诉服务管理器将程序放入后台并为创建PID文件
    start_stop_daemon_args="--background --make-pidfile"

    name="sing-box"
    description="Sing-box Service"

    # 定义依赖,表示需要在网络启动后才启动本服务
    depend() {
    need net
    after firewall
    }

    wq保存并退出。

给服务脚本添加执行权限,这是必须的步骤:

1
chmod +x /etc/init.d/sing-box

将服务添加到开机自启

1
rc-update add sing-box default

立即启动服务

1
rc-service sing-box start

检查服务状态

1
rc-service sing-box status

如果一切正常,您会看到 * status: started 的提示。

如何排错和查看日志?

Alpine 没有像 journalctl 那样集中的日志系统。如果服务启动失败,或者您想查看 Sing-box 的实时输出:

  1. 先停止后台服务

    1
    rc-service sing-box stop
  2. 在前台手动运行程序,这样所有日志都会直接打印在当前窗口:

    1
    /usr/local/bin/sing-box run -c /etc/sing-box/config.json
  3. 排查完毕后,按 Ctrl + C 停止,然后用 rc-service sing-box start 重新在后台启动服务。

hysteria2端口跃迁

假设监听端口为udp 443,通过DNAT实现

在 Alpine 容器内安装 iptables

1
2
apk update
apk add iptables ip6tables

在容器内执行您的重定向命令 这条命令完全不需要修改,直接在容器内执行即可:

1
2
3
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 20000:30000 -j REDIRECT --to-ports 443

ip6tables -t nat -A PREROUTING -i eth0 -p udp --dport 20000:30000 -j REDIRECT --to-ports 443

使规则持久化(非常重要) 直接执行的 iptables 规则在容器重启后会丢失。我们需要让开机自动加载。

1
2
3
4
5
6
# 启动 iptables 服务并设置开机自启
rc-service iptables start
rc-update add iptables default

# 将当前规则保存到配置文件
/etc/init.d/iptables save

执行保存后,您当前的规则会被写入 /etc/iptables/rules-saverules6-save 文件中,并在下次启动时自动加载。