# 路由自定义规则 本文说明 pyxray 配置页“路由 / 自定义规则”的实际语法,以及它最终生成到 Xray `routing.rules` 的方式。 ## 适用入口 | 入口 | 字段 | UI | 适合场景 | | --- | --- | --- | --- | | RoutingA 文本 | `routing.routing_a` | 显示 | 少量域名/IP 前置规则。 | | 结构化规则 | `routing.custom_rules` | 隐藏 | 手写 `settings.toml`,按 geosite/geoip/ext 列表分流。 | pyxray 当前不会让你直接手写完整 Xray `routing.rules` JSON;它只提供上述两种简化输入,然后生成 Xray 规则。 ## 匹配顺序 ```mermaid flowchart TD Request["连接进入 rule 入站或透明代理入站"] --> Custom["先应用 routing_a 前置规则"] Custom --> Mode["再应用 routing.mode 内置规则"] Mode --> Default["最后应用 default_rule 兜底"] Default --> Outbound["proxy direct block"] ``` Xray 原生规则按 `routing.rules` 从上到下匹配,命中第一条后使用该规则的 `outboundTag` 或 `balancerTag`。同一条规则里多个字段同时存在时是 AND 关系;同一字段数组内通常是 OR 关系。 ## RoutingA 文本语法 | 语法 | 示例 | 生成字段 | 说明 | | --- | --- | --- | --- | | `domain(...) -> proxy` | `domain(geosite:google)->proxy` | `domain` | 命中域名后走 `proxy`。 | | `domain(...) -> direct` | `domain(domain:example.com)->direct` | `domain` | 命中域名或子域名后直连。 | | `domain(...) -> block` | `domain(full:ads.example.com)->block` | `domain` | 命中完整域名后阻断。 | | `ip(...) -> proxy` | `ip(geoip:telegram)->proxy` | `ip` | 命中 IP 列表后代理。 | | `ip(...) -> direct` | `ip(geoip:private, geoip:cn)->direct` | `ip` | 命中私有或中国 IP 后直连。 | | 注释 | `# comment` | 无 | 空行和 `#` 开头行会被忽略。 | 格式要求: | 项 | 要求 | | --- | --- | | 匹配器 | 只能是 `domain(...)` 或 `ip(...)`。 | | 分隔符 | 必须使用 `->`。 | | 多个值 | 用英文逗号分隔。 | | 出口 | 通常使用 `proxy`、`direct`、`block`。 | | 生效范围 | 只作用于 rule 入站和透明代理入站,不影响普通 `socks` / `http` 入站。 | 示例: ```toml [routing] mode = "whitelist" default_rule = "proxy" routing_a = """ # 公司内网直连 domain(domain:corp.example.com)->direct ip(10.0.0.0/8, 192.168.0.0/16)->direct # Google 代理 domain(geosite:google)->proxy # 精确阻断广告域名 domain(full:ads.example.com)->block """ ``` ## domain 值 | 写法 | 示例 | 匹配语义 | | --- | --- | --- | | `domain:` | `domain:example.com` | 匹配 `example.com` 和子域名,例如 `www.example.com`。 | | `full:` | `full:example.com` | 只完整匹配 `example.com`。 | | `keyword:` | `keyword:google` | 目标域名包含关键字即匹配。 | | 无前缀字符串 | `google` | 等价于 `keyword:google`。 | | `regexp:` | `regexp:\\.example\\.com$` | 使用正则匹配目标域名。 | | `dotless:` | `dotless:printer` | 匹配不含点的内网短域名。 | | `geosite:` | `geosite:cn` | 使用 `geosite.dat` 里的标签。 | | `ext:` | `ext:geosite.dat:cn` | 从资源目录里的外部 geosite 格式文件读取标签。 | 注意: | 项 | 说明 | | --- | --- | | 推荐默认 | 常规域名优先用 `domain:example.com`。 | | 精确匹配 | 只想匹配单个域名时用 `full:`。 | | 正则转义 | 写进 TOML 字符串时反斜杠要按 TOML 规则转义。 | | 不支持 | `plain:` 不是当前 Xray 官方 routing 文档列出的 domain 前缀,不要使用。 | ## ip 值 | 写法 | 示例 | 匹配语义 | | --- | --- | --- | | 单个 IP | `1.1.1.1` | 匹配目标 IP。 | | CIDR | `10.0.0.0/8` | 匹配网段。 | | IPv6 CIDR | `fc00::/7` | 匹配 IPv6 网段。 | | `geoip:` | `geoip:cn` | 使用 `geoip.dat` 里的国家或分类标签。 | | `geoip:private` | `geoip:private` | 匹配私有地址。 | | `ext:` | `ext:geoip.dat:cn` | 从资源目录里的外部 geoip 格式文件读取标签。 | | `!` 反选 | `!geoip:cn` | 匹配不在该 IP 列表内的目标。 | 示例: ```toml [routing] mode = "routingA" default_rule = "proxy" routing_a = """ ip(geoip:private, geoip:cn)->direct ip(geoip:telegram)->proxy ip(!geoip:cn)->proxy """ ``` ## custom_rules 结构化规则 `custom_rules` 只有在 `routing.mode = "custom"` 时作为主规则集使用。UI 暂不显示,需要手写 `settings.toml`。 | 字段 | 默认值 | 可选值 | 作用 | | --- | --- | --- | --- | | `filename` | `""` | 文件名 | 非空时把每个 tag 生成 `ext::`。 | | `tags` | `[]` | 字符串数组 | 要匹配的 geosite/geoip/ext 标签。 | | `match_type` | `domain` | `domain` / `ip` | 决定生成 Xray rule 的 `domain` 还是 `ip`。 | | `rule_type` | `proxy` | `proxy` / `direct` / `block` | 命中后的出口。 | 示例: ```toml [routing] mode = "custom" default_rule = "proxy" [[routing.custom_rules]] match_type = "domain" rule_type = "direct" tags = ["geosite:private", "geosite:cn"] [[routing.custom_rules]] match_type = "ip" rule_type = "direct" tags = ["geoip:private", "geoip:cn"] [[routing.custom_rules]] match_type = "domain" rule_type = "proxy" tags = ["geosite:geolocation-!cn"] ``` 使用外部文件: ```toml [[routing.custom_rules]] filename = "geosite.dat" match_type = "domain" rule_type = "proxy" tags = ["google"] ``` 上面会生成: ```json { "domain": ["ext:geosite.dat:google"], "outboundTag": "proxy" } ``` ## 常见问题 | 问题 | 原因 | 处理 | | --- | --- | --- | | 规则没生效 | 入口不是 rule 入站或透明代理入站。 | 使用 `rule_http_port` 对应的 mixed 端口,或开启透明代理。 | | 域名规则没命中 | 流量只有 IP,没有域名。 | 开启 sniffing,或改用 `ip(...)` 规则。 | | IP 规则导致 DNS 查询 | 当前 pyxray 生成 `domainStrategy = "IPOnDemand"`。 | 避免过度使用 IP 规则,或接受 Xray 为路由进行 DNS 解析。 | | `routing_a` 里的 `default:` 无效 | pyxray 解析器只识别 `domain(...)` 和 `ip(...)`。 | 用 `default_rule` 设置兜底。 | | `plain:` 无效 | 不是当前 Xray routing 官方 domain 前缀。 | 使用无前缀字符串或 `keyword:`。 | ## 官方依据 | 内容 | 官方链接 | | --- | --- | | Xray RoutingObject / RuleObject | https://xtls.github.io/config/routing.html | | 文档源码 | https://github.com/XTLS/Xray-docs-next/blob/main/docs/config/routing.md | | Xray-core routing 解析代码 | https://github.com/XTLS/Xray-core/blob/main/infra/conf/router.go | | 域名/IP 规则解析代码 | https://github.com/XTLS/Xray-core/blob/main/common/geodata/rule_parser.go |