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:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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" {
|
||||
|
||||
Reference in New Issue
Block a user