daeuniverse / daeuniverse/dae

[Bug Report] `pname(xxx) -> must_rules` 无论是否匹配都会触发

Closed
#474 13 comments 2 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
6.2k
Forks
402
Avg merge
57m
Merged PRs (30d)
2

Description

### Checks

- [X] I have searched the existing issues
- [X] I have read the documentation
- [X] Is it your first time sumbitting an issue

### Current Behavior

首先,我期望除了`systemd-resolved`进行的DNS查询都不被DAE劫持,因此有了如下规则:
```
!pname(systemd-resolved) -> must_rules

dip(geoip:private) -> direct
dip(geoip:cn) -> direct
domain(geosite:cn) -> direct

fallback: proxy
```
这里我们讨论第一条规则,它的效果应该是:

若是`systemd-resolved`产生的流量,应当**不会**触发`must_rules`,随后**被**DAE的DNS模块接管
而其他流量,应该**会**触发`must_rules`,**不被**DAE的DNS模块接管

例如,我这边`systemd-resolved`若查询`raw.githubusercontent.com`会获得`0.0.0.0`
在**没有**第一条规则的默认情况下,**所有**DNS查询都会被DAE劫持,**能够**正常返回结果

加入第一条规则后,**则成功触发第一条规则就不能返回正确结果**

按照第一条规则,通过`systemd-resolved`进行查询时,这条规则应为false,即应当不触发规则并返回正确结果:
```sh
root@router ~# dig raw.githubusercontent.com @127.0.0.53

; <<>> DiG 9.18.24 <<>> raw.githubusercontent.com @127.0.0.53
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39356
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;raw.githubusercontent.com. IN A

;; ANSWER SECTION:
raw.githubusercontent.com. 6 IN A 0.0.0.0

;; Query time: 2 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Sat Mar 09 12:48:37 UTC 2024
;; MSG SIZE rcvd: 70
```
结果却和预期不尽相同,返回了错误结果,也就是说没有经过DAE的DNS(日志也可以佐证这一点),**即触发了这条规则**
若我们直接通过dig查询,此时这条规则应为true,即应当触发规则并返回错误结果:
```sh
root@router ~# dig raw.githubusercontent.com @211.136.150.66

; <<>> DiG 9.18.24 <<>> raw.githubusercontent.com @211.136.150.66
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3111
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;raw.githubusercontent.com. IN A

;; ANSWER SECTION:
raw.githubusercontent.com. 30 IN A 0.0.0.0

;; Query time: 4 msec
;; SERVER: 211.136.150.66#53(211.136.150.66) (UDP)
;; WHEN: Sat Mar 09 12:52:14 UTC 2024
;; MSG SIZE rcvd: 70
```
结果和预期一致

即对于这条规则,**无论哪个经常查询,都会触发(都是true)**

一开始以为是取反在作祟,然后继续测试发现,**不取反也会无条件的一定触发**,例如对于如下规则:
```
pname(systemd-resolved) -> must_rules

dip(geoip:private) -> direct
dip(geoip:cn) -> direct
domain(geosite:cn) -> direct

fallback: proxy
```
和之前的规则是反过来的,**则`systemd-resolved`进行的查询不被劫持,其他都应当劫持**
**但效果却和取反了一样,无论哪个经常查询,都不劫持,则无论如何都触发了`must_rules`.**

更奇怪的是,对于如下规则:
```
!dport(53) && !pname(systemd-resolved) -> must_rules

dip(geoip:private) -> direct
dip(geoip:cn) -> direct
domain(geosite:cn) -> direct

fallback: proxy
```
字面意思应该是,如果不是`systemd-resolved`发的流量,而且还不是DNS流量,就不劫持DNS,其余都劫持
也就是说没有任何DNS流量可以匹配该规则,即所有DNS流量都应当被劫持
但是这条规则却可以无视第一个条件,让所以流量都触发`must_rules`,都不劫持

除此之外,经过测试,只要不涉及`must_rules`,无论是否取反,pname都正确工作,例如:
```
dport(53) && pname(systemd-resolved) -> direct
dport(53) -> must_rules
# Should equal to:
# dport(53) && !pname(systemd-resolved) -> must_rules

dip(geoip:private) -> direct
dip(geoip:cn) -> direct
domain(geosite:cn) -> direct

fallback: proxy
```
可以按照预期实现最开头我想实现的效果

或是
```
!pname(systemd-resolved) -> must_direct #不劫持resolved之外的
fallback: direct #也就是只劫持resolved
```
亦或是
```
pname(systemd-resolved) -> must_direct # 不劫持resolved
fallback: direct #其他都劫持
```
经测试都按照预期效果工作

### Expected Behavior

```
pname(xxx) -> must_rules
...
```

```
!pname(xxx) -> must_rules
...
```

```
!pname(xxx) && ... -> must_rules
...
```
应该按照语义工作

### Steps to Reproduce

例如,创建如下规则:
```
!pname(xxx) -> must_rules
fallback: direct
```
随后观察xxx的DNS流量是否可以进入DAE的DNS模块
应当可以,但是因为`pname = xxx`时`!pname(xxx)`错误的为true,事实上不行

### Environment

- **Dae version (use `dae --version`)**:
在 #466 上测试,上述的问题在0.4.0中表现也基本一致
0.4.0还有一些其他问题,没有做完整的测试
但至少
```
!dport(53) && !pname(systemd-resolved) -> must_rules
```
是可以在所有DNS流量上触发`must_rules`的,这显然是不合理的
- **OS (e.g `cat /etc/os-release`)**:
```
ANSI_COLOR="1;34"
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
BUILD_ID="24.05.20240303.b8697e5"
DOCUMENTATION_URL="https://nixos.org/learn.html"
HOME_URL="https://nixos.org/"
ID=nixos
IMAGE_ID=""
IMAGE_VERSION=""
LOGO="nix-snowflake"
NAME=NixOS
PRETTY_NAME="NixOS 24.05 (Uakari)"
SUPPORT_URL="https://nixos.org/community.html"
VERSION="24.05 (Uakari)"
VERSION_CODENAME=uakari
VERSION_ID="24.05"
```
- **Kernel (e.g. `uname -a`)**:
```
root@router ~# uname -r
6.7.7-zen1
```
- **Others**:

### Anything else?

_No response_

Contributor guide

No contributing guide indexed for this repository

Research direction

No source file or test is named. Start by reproducing the !pname(systemd-resolved) and pname(systemd-resolved) rules with must_rules, then compare them with the working must_direct cases. Done means pname conditions, including negation and conjunction, select must_rules according to their stated semantics for systemd-resolved and other DNS traffic.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, linux
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.