fix(agent): ACL 放行用 auth_user 而非 user(VLESS 运行时只认 auth_user)

生产验证发现:sing-box 1.13 的 route rule 里 user 字段对 VLESS/REALITY
入站运行时不匹配(仅 sing-box check 语法通过),导致放行规则永不命中、
白名单用户也被兜底拒绝。本地真 VLESS 连接实测确认 auth_user 生效
(good→通/bad→block),node 端 git 一进一出白名单验证 per-user 生效。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-23 10:36:02 +08:00
parent e4b527b2c9
commit 2abe4d0816
2 changed files with 16 additions and 8 deletions
+5 -1
View File
@@ -195,7 +195,11 @@ func (ac *ACLConfig) rules() []any {
if len(uuids) > 0 {
for _, t := range targets {
r := t.matchFields()
r["user"] = uuids
// auth_user(非 user):sing-box 1.13 的 route rule 里,VLESS/REALITY 入站的
// 认证用户要用 auth_user 匹配 inbound user 的 name;user 字段对 VLESS 运行时
// 不生效(仅 sing-box check 语法通过),会导致放行规则永不命中、白名单用户也
// 被兜底拒绝。已用本地真 VLESS 连接实测确认(good→通, bad→被 block)。
r["auth_user"] = uuids
r["outbound"] = directOutboundTag
out = append(out, r)
}
+11 -7
View File
@@ -213,11 +213,15 @@ func TestACLRules_AllowThenDeny(t *testing.T) {
t.Fatalf("规则数 = %d, want 4 (2 target × 放行+拒绝)", len(rules))
}
// 前两条是放行:带 user + outbound,不带 action
// 前两条是放行:带 auth_user + outbound,不带 action
// (auth_user 而非 user:VLESS 入站运行时只认 auth_user,见 acl.go rules() 注释)
for i := 0; i < 2; i++ {
r := rules[i].(map[string]any)
if _, ok := r["user"]; !ok {
t.Errorf("rules[%d] 放行规则缺 user", i)
if _, ok := r["auth_user"]; !ok {
t.Errorf("rules[%d] 放行规则缺 auth_user", i)
}
if _, ok := r["user"]; ok {
t.Errorf("rules[%d] 放行规则不应带 user(VLESS 不生效),应用 auth_user", i)
}
if r["outbound"] != directOutboundTag {
t.Errorf("rules[%d] outbound = %v, want %q", i, r["outbound"], directOutboundTag)
@@ -226,14 +230,14 @@ func TestACLRules_AllowThenDeny(t *testing.T) {
t.Errorf("rules[%d] 放行规则不应带 action", i)
}
}
// 后两条是拒绝:带 action=reject,不带 user(对所有人生效)
// 后两条是拒绝:带 action=reject,不带 auth_user(对所有人生效)
for i := 2; i < 4; i++ {
r := rules[i].(map[string]any)
if r["action"] != "reject" {
t.Errorf("rules[%d] action = %v, want reject", i, r["action"])
}
if _, ok := r["user"]; ok {
t.Errorf("rules[%d] 拒绝规则不应带 user,否则会漏掉名单外的人", i)
if _, ok := r["auth_user"]; ok {
t.Errorf("rules[%d] 拒绝规则不应带 auth_user,否则会漏掉名单外的人", i)
}
}
@@ -331,7 +335,7 @@ func TestBuildRoute_Matrix(t *testing.T) {
if rules[1].(map[string]any)["action"] != "resolve" {
t.Error("第二条不是 resolve")
}
if _, ok := rules[2].(map[string]any)["user"]; !ok {
if _, ok := rules[2].(map[string]any)["auth_user"]; !ok {
t.Error("第三条不是放行规则")
}
if rules[3].(map[string]any)["action"] != "reject" {