fix(xray): keep source- and domains-scoped routing rules when an inbound is deleted

removeInboundTagFromRules drops a routing rule whose inboundTag list becomes
empty only if the rule has no other matcher, but routingMatcherKeys omitted
xray-core's canonical source and domains keys. A rule scoped by source or domains
(common in hand-authored or imported configs) therefore lost its whole body —
including a security-relevant block — when its single listed inbound was deleted,
instead of just having the tag trimmed. Recognize source and domains as live
matchers.
This commit is contained in:
MHSanaei
2026-07-15 03:17:33 +02:00
parent aaf17bcfdc
commit 8c63f7cc81
2 changed files with 35 additions and 2 deletions
@@ -5,8 +5,8 @@ import (
)
var routingMatcherKeys = []string{
"domain", "ip", "port", "sourcePort", "localPort", "network",
"sourceIP", "localIP", "user", "vlessRoute", "protocol", "attrs", "process",
"domain", "domains", "ip", "port", "sourcePort", "localPort", "network",
"source", "sourceIP", "localIP", "user", "vlessRoute", "protocol", "attrs", "process",
}
func readInboundTags(raw any) []string {
@@ -158,6 +158,39 @@ func TestRemoveInboundTagReferences_KeepsRuleWithOtherMatchers(t *testing.T) {
}
}
func TestRemoveInboundTagReferences_KeepsSourceScopedRule(t *testing.T) {
setupSettingTestDB(t)
seedXrayTemplate(t, `{
"routing": {
"rules": [
{
"type":"field",
"inboundTag":["in-443-tcp"],
"source":["10.0.0.0/8"],
"outboundTag":"blocked"
}
]
}
}`)
svc := &XraySettingService{}
if _, err := svc.RemoveInboundTagReferences("in-443-tcp"); err != nil {
t.Fatalf("RemoveInboundTagReferences: %v", err)
}
got, err := svc.GetXrayConfigTemplate()
if err != nil {
t.Fatalf("GetXrayConfigTemplate: %v", err)
}
rule := findRuleByOutbound(t, got, "blocked")
if _, ok := rule["inboundTag"]; ok {
t.Fatalf("inboundTag should be trimmed, rule = %#v", rule)
}
if src, _ := rule["source"].([]any); len(src) != 1 {
t.Fatalf("source-scoped rule was dropped instead of kept; rule = %#v", rule)
}
}
func TestRemoveInboundTagReferences_RemovesOneTagFromMultiInboundRule(t *testing.T) {
setupSettingTestDB(t)
seedXrayTemplate(t, `{