Skip to content

Conversation

@patterniha
Copy link
Collaborator

@patterniha patterniha commented Sep 12, 2025

suppose we want to route domains with range-A IPs to outbound-1, and route others to outbound-2,
and domains with range-A IPs should not be routed to outbound-2 under any circumstances.

so the config is:

"domainStrategy": "IPOnDemand",
    "rules": [
           {"outboundTag": "outbound-1", // rule-1
            "ip": ["range-A"]
           },
           {"outboundTag": "outbound-2", // rule-2
            "network": "tcp,udp"
           }
    ]

suppose the domain "example.com" has ip in range-A, but built-in-dns-servers are unavailable for a while(for any reason), so domain failed to resolve to ip and rule-1 does not apply and rule-2 apply and "example.com" route to outbound-2!!! but "example.com" has range-A ip and should not route to outbound-2.

there are many examples where domains with certain range IPs should not be routed to a specific outbound.

///

As a result, in "IPOnDemand"/"IPIfNonMatch" mode, when a domain failed to resolve to ip(after encountering an ip-rule), router should return error immediately and should not select any outbound.

@RPRX
Copy link
Member

RPRX commented Sep 16, 2025

我不确定这个是否应该导到默认出站,router 里其它项有这类问题吗

@patterniha
Copy link
Collaborator Author

patterniha commented Sep 16, 2025

我不确定这个是否应该导到默认出站

routing to default-outbound is for when no-rule-matched not domain-failed-to resolve.

in my example "network": "tcp,udp" rule may be omitted, so the problem still remains and it route to wrong outbound.

///

router 里其它项有这类问题吗

All other values are already specified in inbounds, only resolve-domain-to-ip takes a while and it may return error.

@yuhan6665
Copy link
Member

My opinion is, this is not a problem. If you don't have IP, it will not match IP rule and go to other rules. User need to define reasonable default outbound.

@yuhan6665 yuhan6665 closed this Oct 6, 2025
@patterniha
Copy link
Collaborator Author

patterniha commented Oct 6, 2025

@yuhan6665

I want to bypass(route direct) all Iran/China-IPs-Domains and use proxy(or fragment) for others.

Can you tell me how I can do this so that I can be sure that no Iran/China-IPs-Domain passes through the proxy? (I use fakedns)

///

The problem is not that a domain may not have an IP address, the problem is that a DNS-Server may be unavailable for just a few moments for whatever reason.

///

This is a fundamental and security problem, so i reopen it.

@patterniha patterniha reopened this Oct 6, 2025
@Fangliding
Copy link
Member

。。。

@Fangliding
Copy link
Member

总是考虑临时不可用的DNS服务器会很麻烦 上次被恶心的是ECH record查询 这路由又来

@Meo597
Copy link
Collaborator

Meo597 commented Oct 6, 2025

想要安全性

未知域没能解出来ip,或者国外ip
一定是默认走代理的

这不是理由,不知道在乱改什么

@patterniha
Copy link
Collaborator Author

patterniha commented Oct 6, 2025

未知域没能解出来ip,或者国外ip
一定是默认走代理的

It's not a domain problem, it's a dns-server problem, dns-servers may be unavailable for just a moment, for any reason(packet-lost, ...)
China/Iran-Websites shouldn't notice our proxy-server-IP(or use fragment for them), this is important problem.

@yuhan6665
Copy link
Member

Can you change to default direct, some IP to direct and all other IPs to proxy

@patterniha
Copy link
Collaborator Author

Can you change to default direct, some IP to direct and all other IPs to proxy

This creates other problems, for example foreign-cryptocurrency-websites can see my real-IP, and ban my account(Iran is sanctioned).

so domestic-websites should bypass and foreign-websites should pass through the proxy, and neither should replace the other.

@yuhan6665
Copy link
Member

You can try default to blackhole

@patterniha
Copy link
Collaborator Author

You can try default to blackhole

I already thought about it, the problem is that we make a DNS request after encountering each rule.

for example if we have 10 IP-rules and dns-server is not available we send 10 dns-requests and wait 40-seconds!(suppose each request-timeout is 4 seconds)

///

also, we may have more than 2-IP-rule(or 2-ip-rule with multiple IPs), so default-blackhole-idea does not work.

for example, in serverless-for-Iran i want:

"ip": ["geoip:ir", "geoip:private"] -> bypass
"ip": ["geoip:cloudflare"] -> ech-MitM
"ip": [others] -> fragment

So how can you make sure these rules are always strictly enforced?

@Meo597
Copy link
Collaborator

Meo597 commented Oct 6, 2025

第一,解不出来ip就应该走代理
代理那边也会解析并触发封锁,不存在国内流量被代理问题

第二,解不出来ip直接封锁也可以

第三,路由模块只会发起一到两次dns请求
不是每rule都请求一次

这三点无论哪一条都能解决你的需求
收了神通吧,求求了

@patterniha
Copy link
Collaborator Author

patterniha commented Oct 6, 2025

Second, if you can’t figure out the IP address, you can just block it.

how? This is exactly what this PR does.

Third, the routing module only makes one or two DNS requests
, not one for each rule.

No, we have separate requests for each IP-rule, until we get a response and cache the result, then we use the cache for other-IP-rules.
so if we don't get any response we send dns-request for each IP-rule and wait 4-seconds(at least) for each rule. you can read the code.

@Meo597
Copy link
Collaborator

Meo597 commented Oct 6, 2025

解不出来ip,你就不知道该如何分流,说明是未知域
意味着不会命中任何ip和domain规则

只需要默认block就行了

然后路由模块发起dns请求次数问题
我已经看过代码,不想争论,不予置评

@patterniha
Copy link
Collaborator Author

patterniha commented Oct 6, 2025

@Meo597 @yuhan6665

In short, if you solve this problem, i close this PR:

"ip": [ip-A, ip-B] -> out1
"ip": [others] -> out2
"ip":[cannot resolve] -> block

How can I strictly enforce these rules?

@wyx2685
Copy link
Contributor

wyx2685 commented Oct 6, 2025

@patterniha 没路由就应该发默认出口 就该减少本地解析次数

@patterniha
Copy link
Collaborator Author

patterniha commented Oct 6, 2025

意味着不会命中任何ip和domain规则

No, this is completely wrong, if a rule does not have "ip": [...], the domain does not resolve to the IP. we talk about "IPOnDemand"/"IPIfNonMatch" mode and when using fakedns(read the first comment).

@patterniha
Copy link
Collaborator Author

patterniha commented Oct 6, 2025

https://github.com/XTLS/Xray-core/blob/3edfb0e33557330ac721862adb2e4be89ee7412a/app/router/router.go#L184-214

this is exactly what i say, if a rule does not apply, we go to next-rule. and if a domain failed to resolve to IP(and we use "IPOnDemand"/"IPIfNonMatch"), the IP-rule(rule which has "ip":[...] condition) does not apply.

but if a rule does not have ‍"ip": [...] the rule is applied(If the other conditions are true), even the domain cannot resolve to the IP, because we does not use built-in-dns at all.

@patterniha
Copy link
Collaborator Author

I think the discussion got a bit messy, In short, In many situations we want to:

"ip": [ip-A, ip-B, ...] -> out1
"ip": [others] -> out2
"ip":[cannot resolve] -> block

And this PR ensures that these rules are strictly enforced.

@patterniha
Copy link
Collaborator Author

I thought about it and found another solution.

the problem is that we make a DNS request after encountering each rule, and we only cache the successful query.
for example if we have 10 IP-rules and dns-server is not available we send 10 dns-requests and wait 40-seconds!(suppose each request-timeout is 4 seconds)

if len(ctx.resolvedIPs) > 0 {
return ctx.resolvedIPs
}

if err == nil {
ctx.resolvedIPs = ips
return ips
}

so we should cache the error as well, otherwise we have dns-request for each IP-rule(if dns-server is not available), and this cause many problems(choosing wrong outbound, waiting too long and ...)

also, i can achieve my goal by adding "ip": ["0.0.0.0/0", "::/0"] to each rule.

so i close this PR, and open a new PR for caching dns-error.

@patterniha patterniha closed this Oct 6, 2025
@yuhan6665
Copy link
Member

Please don't cache error, each new DNS request must be retry again

@patterniha
Copy link
Collaborator Author

Please don't cache error, each new DNS request must be retry again

so if we have 10 IP-rules we have 10 dns-requests and we wait 40 seconds!!!

also how to solve: #5138 (comment)

@yuhan6665 i think you misunderstood, this cache is only for router in "IPIfNonMatch"/"IPIfNonMatch" mode.

in routing we need to use built-in-dns only once for all rules.

this cache is only used for one-dispatch and we don't have this cache for next-dispatch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants