mihomo icon indicating copy to clipboard operation
mihomo copied to clipboard

[Feature] sub-rule 的几个建议

Open lesca opened this issue 2 years ago • 8 comments

Verify steps

  • [X] 我已经在 Issue Tracker 中找过我要提出的请求 I have searched on the issue tracker for a related feature request.
  • [X] 我已经仔细看过 Documentation 并无法找到这个功能 I have read the documentation and was unable to solve the issue.

Description

目前我了解到的 sub-rule 的使用方式:sub-rule,条件,子规则名

rules:
  - SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),sub-rule-name1 

sub-rules:
  sub-rule-name1:
    - DOMAIN,google.com,ss1
    - DOMAIN,baidu.com,DIRECT
    - ...

几个问题期待改进:

  1. 不支持无条件跳转 上例中的条件(OR,((NETWORK,TCP),(NETWORK,UDP)))在我看来等价于“无条件”,因为已经包含了我平时用到的所有情况(有例外吗?)。希望能够优化这种无条件,因为:

    1. 每次匹配到 sub-rule 时,都需要对 UDP TCP 进行判断,影响性能。
    2. sub-rules中已经定义了条件。

我非常理解SUB-RULE进行预先的条件判断,在某些场景下可以节省算力、提高效率,但是也请考虑不需要判断的情况。

希望能实现类似MATCH的语法:SUB-RULE,,sub-rule-name1 或者直接省略 SUB-RULE,sub-rule-name1 来实现无条件跳转!!

  1. 不支持嵌套 下面的例子中,希望将sub-rule-reused重复利用在sub-rules中,但是会直接报错: 2023-07-15 19:55:22 level=error msg="sub-rules[sub-rule-name1][2] [SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),sub-rule-reused] error: sub-rule [sub-rule-reused] not found"
sub-rules:
  sub-rule-resued:
    - IP-CIDR,172.17.0.0/16,proxy
    - GEOIP,LAN,DIRECT
    - MATCH,proxy
  sub-rule-name1:
    - GEOSITE,CN,DIRECT
    - SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),sub-rule-reused
  1. 日志意义不明(如下)。应该描述 sub-rules 中的哪一条规则或条件,而不是 TCP UDP 被满足了。
2023-07-15 21:40:28 level=info msg="[TCP] 192.168.2.222:65363 --> 192.168.2.13:9090 match SubRules((OR,((NETWORK,TCP),(NETWORK,UDP)))) using DIRECT"

Possible Solution

No response

lesca avatar Jul 15 '23 14:07 lesca

@lesca 1,如果不需要判断,直接写在rules不就行了? 如

rules:
  - DOMAIN,google.com,ss1
  - DOMAIN,baidu.com,DIRECT
  - SUB-RULE,(xxx,xxx),sub-rule-name1 

sub-rules:
  sub-rule-name1:
    - xxx,xxx
    - ...

2,如果未匹配到,会回退rules,你在下面写不就行了?

rules:
  - SUB-RULE,(xxx,xxx),sub-rule-name1 
  - SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),sub-rule-reused
sub-rules:
  sub-rule-resued:
    - IP-CIDR,172.17.0.0/16,proxy
    - GEOIP,LAN,DIRECT
    - MATCH,proxy
  sub-rule-name1:
    - GEOSITE,CN,DIRECT

xishang0128 avatar Jul 15 '23 16:07 xishang0128

1 其实就从一次条件变成了,现在的两次;但是加这个条件之后,其实对于所有 子规则都需要判断一次他是否是空,总的来说意义不算大。如 @xishang0128 说的不分支写在 rules 里面是最好的 2 设计上是支持嵌套的,应该是配置解析出现了 Bug,不过在此之前,你先尝试 sub-rule-resued sub-rule-reused 纠正这两个错误试试 3 由于 Sub-Rules 是设计成的类似 DOMAIN,IP-CIDR 的整体,他的匹配是内部进行的,所以没法在规则匹配时影响这个最终日志

Skyxim avatar Jul 16 '23 02:07 Skyxim

https://github.com/MetaCubeX/Clash.Meta/commit/f73f32e41cba9969a1fc6fd7642897ce9fa64e59 调整了下解析

Skyxim avatar Jul 16 '23 02:07 Skyxim

感谢回复 @Skyxim

1 其实就从一次条件变成了,现在的两次;但是加这个条件之后,其实对于所有 子规则都需要判断一次他是否是空,总的来说意义不算大。如 @xishang0128 说的不分支写在 rules 里面是最好的

在我看来,sub-rules 可以根据使用场景,定义规则集,并重复利用在 rules, sub-rules, listeners中。想象空间很大。例如可以实现根据使用场景切换规则的能力,这是单个rules所不能及的。

“无条件”现在可以通过(OR,((NETWORK,TCP),(NETWORK,UDP)))实现,但是如果调用量巨大(例如嵌套),会造成性能浪费。这是我担忧的地方,所以才建议允许省略这类判断。

2 设计上是支持嵌套的,应该是配置解析出现了 Bug,不过在此之前,你先尝试 sub-rule-resued sub-rule-reused 纠正这两个错误试试

抱歉。这个reused是我为了方便理解临时改的。这里有拼写错误,原始配置是复制粘贴的。我这里重新检查尝试了一下,还是一样会报错 not found

3 由于 Sub-Rules 是设计成的类似 DOMAIN,IP-CIDR 的整体,他的匹配是内部进行的,所以没法在规则匹配时影响这个最终日志

理解。这是个better to have 的特性。只是目前的日志对调试并不友好。

lesca avatar Jul 16 '23 04:07 lesca

强大subrule特性支持可以简化配置,提高复用,希望能实现。

XinyuWuu avatar Jul 16 '23 06:07 XinyuWuu

alpha最新版测试,仍然不支持嵌套 如下配置测试走的是直连

rules:

  • SUB-RULE,(DOMAIN-SUFFIX,browserleaks.com),SR1
  • MATCH,REJECT

sub-rules: SR1: - SUB-RULE,(DOMAIN-SUFFIX,browserleaks.com),SR2 - MATCH,DIRECT SR2: - DOMAIN-SUFFIX,browserleaks.com,🌎 - MATCH,🌎

Brbrbr1995 avatar Dec 06 '23 01:12 Brbrbr1995

sub-rule in rule-provider 也无效,配置如下,测试是走直连

rule-providers:
  RPT:
    type: http
    behavior: classical
    url: "http://192.168.1.14/Rule/RPT.yaml"
    path: ./Provider/Rule/RPT.yaml
    interval: 3600

rules:
  - RULE-SET,RPT,REJECT
  - MATCH,DIRECT

sub-rules:
  SR2:
    - DOMAIN-SUFFIX,browserleaks.com,REJECT
    - MATCH,REJECT

RPT.yaml:

payload:
  - SUB-RULE,(DOMAIN-SUFFIX,browserleaks.com),SR2

Brbrbr1995 avatar Dec 06 '23 02:12 Brbrbr1995

赞成改进 SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),sub-rule-name1 这种,我觉得能保持配置文件简洁。不然的话得单独建个远程的 rule-set,这是我的情况:

  rules:
    ...
    - SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),1reject
    - SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),1proxy
    ...

  sub-rules:
    1reject:
      # AnyGo
      - DOMAIN,order.luckydogsoft.com,🛑 自定义拦截
      - DOMAIN,ip-api.com,🛑 自定义拦截
      # sublime
      - DOMAIN,www.sublimetext.com,🛑 自定义拦截
      - DOMAIN,license.sublimehq.com,🛑 自定义拦截
    1proxy:
      # copilot
      - DOMAIN-SUFFIX,githubcopilot.com,🔰 Proxy
      # coze
      - DOMAIN-SUFFIX,coze.com,🔰 Proxy
      # 一加海外社区
      - DOMAIN-SUFFIX,community.oneplus.com,🔰 Proxy

pillarcoin avatar Nov 24 '24 20:11 pillarcoin

强烈希望支持 sub-rules 复用 RULE-SET,用来对相同应用进行分组

rules:
    ...
    - SUB-RULE,(OR,((NETWORK,TCP),(NETWORK,UDP))),super-subrule-google
    ...

sub-rules:
    super-subrule-google:
      - RULE-SET: Google / Domain,🔰 Proxy
      - RULE-SET: Google / IP,🔰 Proxy,no-resolve
      - DOMAIN,www.google-other.com,🔰 Proxy
      - IP-CIDR,8.8.8.8,🔰 Proxy
    ...

rule-anchor:
  ip: &ip { type: http, interval: 86400, behavior: ipcidr, format: mrs }
  domain: &domain { type: http, interval: 86400, behavior: domain, format: mrs }
  class: &class { type: http, interval: 86400, behavior: classical, format: text }
  file: &file { type: file, interval: 300, behavior: domain, format: text }

rule-providers:
  Google / Domain: { <<: *domain, url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/google.mrs" }
  Google / IP: { <<: *ip, url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/google.mrs"}

目前是无法支持的:

yaml: unmarshal errors:
  line 48: cannot unmarshal !!map into string
  line 49: cannot unmarshal !!map into string

onion83 avatar Jun 14 '25 18:06 onion83