在 Oracle VPS 上部署 sing-box 代理
在 Oracle Cloud 免费实例上用 systemd 部署 sing-box,提供 Shadowsocks、VLESS-WS+TLS(Cloudflare 前置)与 VLESS-Reality 三种入站,含 OCI 防火墙与配置要点。
#type / howto
#status / evergreen
#tech / network
#tech / security
#tech / ops / cloud
[!info] related notes
- 排障与坑位:Oracle VPS 代理部署的坑
- 节点优选:Cloudflare 优选 IP
- 本机记录:oracle-vps
- 背景:甲骨文免费服务器回收问题调研
在 Oracle VPS 上部署 sing-box 代理
一句话定义
在 Oracle Cloud 免费实例上以 sing-box 作为代理服务端,对外暴露多个入站协议,配合 OCI 安全列表放行 + Cloudflare 前置,让客户端从中国大陆稳定连出。
为什么这样部署
Oracle 免费实例(AMD E2.Micro / ARM A1)网络出口在中国大陆会被 GFW 重点关照:
- 直连暴露的代理端口(尤其 VLESS-Reality)会被链路层黑洞——详见 坑位清单。
- 因此采用「直连 SS 保速度 + Cloudflare 前置 WS/TLS 保连通」的双栈策略:SS 直连最快,CF 前置抗封锁。
拓扑:三个入站
| 入站 | 端口 | 协议 | 用途 | 前置 |
|---|---|---|---|---|
ss | 80 | Shadowsocks (2022-blake3-aes-128-gcm) | 主用,延迟最低 | 直连 |
vless-ws | 443 | VLESS + WebSocket + TLS(自签证书) | 备用,抗封锁 | Cloudflare 橙色云朵 |
VLESS-Reality | 8443 | VLESS + Reality | 实测被 GFW 拦,基本不可用 | 直连(已证伪) |
端口选择:80/443 是 OCI 与多数网络默认可出的;8443 用来「一锤定音」验证 Reality 是否真的被拦(结论:被拦)。
安装(systemd)
# 下载官方 release(版本以官网为准),解压后放到 /usr/bin/sing-box
# 配置放 /etc/sing-box/config.json
sudo systemctl enable --now sing-box
systemctl is-active sing-box # 应为 active
ss -tlnp | grep -E ':(80|443|8443) ' # 确认三个端口在监听
配置骨架(已脱敏,密钥用占位符)
{
"log": { "level": "info", "timestamp": true },
"dns": {
"final": "local",
"servers": [
{ "tag": "local", "address": "local" },
{ "tag": "google", "address": "8.8.8.8" },
{ "tag": "cloudflare", "address": "1.1.1.1" }
],
"rules": [
{ "domain": ["updates.cdn-apple.com"], "server": "local" }
]
},
"inbounds": [
{
"type": "shadowsocks",
"tag": "ss",
"listen": "::",
"listen_port": 80,
"method": "2022-blake3-aes-128-gcm",
"password": "<SS_PASSWORD>",
"multiplex": { "enabled": true, "protocol": "h2" }
},
{
"type": "vless",
"tag": "vless-ws",
"listen": "::",
"listen_port": 443,
"users": [ { "uuid": "<UUID>", "flow": "xtls-rprx-vision" } ],
"tls": {
"enabled": true,
"certificate_path": "/etc/sing-box/tls/cert.pem",
"key_path": "/etc/sing-box/tls/key.pem"
},
"transport": { "type": "ws", "path": "/vlessws" }
},
{
"type": "vless",
"tag": "VLESS-Reality",
"listen": "::",
"listen_port": 8443,
"users": [ { "uuid": "<UUID>", "flow": "xtls-rprx-vision" } ],
"tls": {
"enabled": true,
"server_name": "updates.cdn-apple.com",
"reality": {
"enabled": true,
"handshake": { "server": "23.48.x.x", "server_port": 443 },
"private_key": "<REALITY_PRIVATE_KEY>",
"short_id": ["<SHORT_ID>"]
}
}
}
],
"outbounds": [ { "type": "direct", "tag": "direct" } ]
}
要点:
listen: "::"表示双栈监听,确保 IPv4 可达(Oracle 免费实例没有公网 IPv6,见坑位)。dns.final: local是关键:Reality 的handshake目标(如updates.cdn-apple.com)要走本地解析,避免 sing-box 用出站 DNS 去解析一个会优先返回 IPv6 的域名导致 dial 失败。- Reality 的
handshake直接写死 IPv4(23.48.x.x:443),而不是依赖域名解析——这是修过failed to dial dest: invalid address后的正确写法。
OCI 防火墙(安全列表 / NSG)
- 默认安全列表只放行 22(SSH)和 ICMP,必须手动加 ingress 规则:
- 80:TCP + UDP(Shadowsocks 是 UDP,只开 TCP 不通)→ 或选「All Protocols」。
- 443:TCP。
- 8443:TCP(仅用于验证 Reality)。
- 改完可用本机
Test-NetConnection <VPS_IP> -Port 443验证(但注意:国内返回TcpTestSucceeded: True也可能是 GFW 伪造的 SYN-ACK,不能当连通证据,见坑位)。
客户端配置要点
- SS 节点:填
server: <VPS_IP>、port: 80、method: 2022-blake3-aes-128-gcm、password: <SS_PASSWORD>。 - VLESS-WS 节点(Cloudflare 前置):
server: oracle1.<your-domain>、port: 443、path: /vlessws、TLS 走系统/自签(客户端通常不校验自签,或关掉skip-cert-verify视客户端而定),sni填你的域名。 - Reality 节点:
server: <VPS_IP>、port: 8443、public-key: <由 private_key 推导>、short-id: <SHORT_ID>、servername: updates.cdn-apple.com。- ⚠️ public-key 必须用
cryptography库从 private_key 反推验证,不要手写 X25519(极易算错,曾因此误判「公钥写错」)。验证脚本见 坑位-公钥校验。
- ⚠️ public-key 必须用
验证部署是否真的通
不要只信端口扫描。在服务器本机用正确公钥、走 127.0.x.x:8443 起一个临时 sing-box 客户端自测:
# 服务器端 127.0.x.x 自测(证明配置本身 OK)
curl -x http://127.0.x.x:<本地代理端口> -o /dev/null -w "HTTP=%{http_code}\n" http://example.com
# 期望 HTTP=200,且 journalctl -u sing-box 出现 inbound/vless[VLESS-Reality] 入站记录
服务器侧能通、客户端侧不通 = 链路(GFW/出境)问题,不是配置问题。
推荐节点优先级(实测)
| 节点 | 实测延迟 | 结论 |
|---|---|---|
| SS 直连(:80) | ~307ms | 🥇 主用,最快 |
| CF 优选 IP(:443) | ~1792ms | 🥈 备用,抗封锁 |
| CF 域名(:443) | ~4189ms | 备用,绕路时更慢 |
| Reality 直连(:8443) | 超时 | 🚫 国内连不上,弃用 |
节点优选方法见 Cloudflare 优选 IP。