feat: 请求支持socks/http端口复用
背景
本地入站目前 SOCKS 和 HTTP 各占一个端口(例如 1080 + 8080)。浏览器走 HTTP CONNECT,CLI / 部分应用走 SOCKS5,部署时要开两个 listener、记两套地址,系统代理也只能填其中一个。
这两个协议首包就能分开,没有必要各占一个端口。
期望行为
同一个 listen 地址 + 端口同时接受:
- SOCKS4 / SOCKS4a / SOCKS5
- HTTP CONNECT(以及普通 HTTP 代理请求,如
GET http://host/)
客户端无需改配置:socks5://127.0.0.1:7890 和 http://127.0.0.1:7890 指向同一端口即可。
独立的 socks / http inbound 继续保留,复用作为新增能力。
协议识别
TCP accept 后 peek 第一个字节再分流,peek 过的字节必须回灌给后续 handshake,不能丢掉:
| 首字节 | 协议 |
|---|---|
0x04 |
SOCKS4 / SOCKS4a |
0x05 |
SOCKS5 |
其它(常见 C/G/P/H 等 ASCII) |
HTTP |
既不是 SOCKS 也解析不成 HTTP 的连接直接关闭,不要卡住 listener。
UDP Associate 仍走 SOCKS5;HTTP 入站不提供 UDP。
鉴权
SOCKS 和 HTTP 共用同一套账号。SOCKS5 username/password 开了之后,HTTP 用相同的 Basic Auth(Proxy-Authorization)。一边通过、另一边匿名可进,等于鉴权失效。
已有实现
Xray
SOCKS inbound 默认兼容 HTTP,不再需要单独的 mixed 开关(旧字段 mixed 已废弃)。
首字节不是 0x04/0x05 时,把连接连同已读字节转给内置 HTTP handler。鉴权账号两边共用。
{
"listen": "127.0.0.1",
"port": 1080,
"protocol": "socks",
"settings": {
"auth": "password",
"udp": true,
"accounts": [
{ "user": "alice", "pass": "secret" }
]
}
}
文档:Socks inbound(明确写了兼容 HTTP)。
实现:XTLS/Xray-core#3682,proxy/socks/server.go 首字节分流。
验证:
curl -x socks5h://127.0.0.1:1080 https://example.com -o /dev/null
curl -x http://127.0.0.1:1080 https://example.com -o /dev/null
sing-box
独立 inbound 类型 mixed:先 peek 1 字节,0x04/0x05 走 SOCKS,其余走 HTTP。
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 7890,
"users": [
{ "username": "alice", "password": "secret" }
]
}
文档:Inbound / Mixed。
实现:protocol/mixed/inbound.go。
Clash / mihomo 的 mixed-port 是同一类能力,行为可对照,实现以 Xray / sing-box 为准即可。
建议落地
配置上二选一即可:
- Xray 路线:现有 SOCKS inbound 默认附带 HTTP 识别(改动小,用户不用换 inbound 类型)。
- sing-box 路线:新增
mixedinbound,SOCKS / HTTP 纯协议入口保持不变。
倾向 1:现有只开了 SOCKS 的用户直接受益,浏览器和 curl -x http:// 不用再加端口。
实现要点:
- peek 后把首字节塞回 reader(buffered reader /
UnreadByte) - 鉴权账号两边同一套
- SOCKS5 UDP 不受 HTTP 分流影响
- 非法首包尽快断开
- 文档和示例改成一个端口;changelog 写明旧的双端口配置仍然有效
验收
- 同一端口:
curl -x socks5h://127.0.0.1:<port>与curl -x http://127.0.0.1:<port>都能通 - 配置了用户密码时,两种协议都要带同一组凭据,缺凭据都拒绝
- SOCKS5 UDP Associate 仍可用(若当前已支持 UDP)
- 只开 SOCKS 或只开 HTTP 的旧配置行为不变
Source: v2fly/v2ray-core