Xray-core icon indicating copy to clipboard operation
Xray-core copied to clipboard

[Feature request]Resolve DNS immediately and use IP as destination instead of domain

Open mazzz1y opened this issue 1 year ago • 18 comments

I have chain of xray servers and want to use DNS resolver on the first server, but can't find a way how I can to do it. When client send request with domain as destination it will resolve domain on the last server. Routing rules don't change destination domain to ip as described in v2ray docs:

The resolved IPs are only used for routing decisions, the traffic is still sent to original domain address.

Is it possible to resolve it on xray server immediately? I want something like domainStrategy: "UseIP" which is available only for "freedom" outbound.

mazzz1y avatar Jul 25 '22 11:07 mazzz1y

SniffingObject 增加 routeOnly 选项 为 true 时: 嗅探出的域名仅作用于路由 代理目标地址仍然为 IP https://github.com/XTLS/Xray-core/commit/a3023e43ef55d4498b1afbc9a7fe7b385138bb1a

因为不知道你的vps配置文件内容,建议你尝试此参数。来自xray 1.5.1的更新日志里。

chika0801 avatar Jul 25 '22 11:07 chika0801

Thank you for response,

It is already routeOnly: true,

Sniffing feature parses SNI domain from http header and routes traffic based on this SNI domain name.

RouteOnly parameter means that this parsed domain will be used only for routing purposes and will not change destination. If this parameter is not present destination will be replaced from IP to Domain from SNI header. As I understand it

I want vice versa feature. I want to resolve destination domain immediately and use IP as destination for all requests.

mazzz1y avatar Jul 25 '22 12:07 mazzz1y

透明代理就是你说的这样 https://xtls.github.io/document/level-2/transparent_proxy/transparent_proxy.html

yuhan6665 avatar Jul 25 '22 14:07 yuhan6665

Yes, I know it, but I want to use it with vless/ss/socks clients. It will helpful when you have multiple clients which using different protocols and clients

mazzz1y avatar Jul 25 '22 14:07 mazzz1y

Transparent proxy just mean how the traffic enters in the client, you can use it with whatever client or protocol you want.

yuhan6665 avatar Jul 25 '22 14:07 yuhan6665

@yuhan6665 maybe I missed something, I can configure dokodemo-door/tproxy and forward traffic via iptables on linux pc. But how I can use it with shadowsocks-android client for example?

mazzz1y avatar Jul 25 '22 14:07 mazzz1y

shadowsocks-android or v2rayNG uses VPN service. It function very much like transproxy. All you need to do is disable sniffing or use routeOnly option (xray-core) https://github.com/2dust/v2rayNG/wiki/Mode#vpn-mode

yuhan6665 avatar Jul 25 '22 14:07 yuhan6665

我参考了这个文章 https://gist.github.com/phlinhng/c11c1268748874982fa6596fb0a4992a

我改了一下配置,但是我没有测试过,你可以自己测试一下 VPS A

{
    "log": {
        "access": "",
        "error": "",
        "loglevel": "warning"
    },
    "dns": {
        "servers": [
            "https+local://1.1.1.1/dns-query"
        ],
        "queryStrategy": "UseIPv4"
    },
    "inbounds": [
        {
            "listen": "0.0.0.0",
            "port": 443,
            "protocol": "vless",
            "settings": {
                "clients": [
                    {
                        "id": "chika",
                        "flow": "xtls-rprx-direct"
                    }
                ],
                "decryption": "none",
                "fallbacks": [
                    {
                        "dest": "8001",
                        "xver": 1
                    },
                    {
                        "alpn": "h2",
                        "dest": "8002",
                        "xver": 1
                    }
                ]
            },
            "streamSettings": {
                "network": "tcp",
                "security": "xtls",
                "xtlsSettings": {
                    "rejectUnknownSni": true,
                    "minVersion": "1.3",
                    "certificates": [
                        {
                            "certificateFile": "/etc/ssl/private/fullchain.cer",
                            "keyFile": "/etc/ssl/private/private.key"
                        }
                    ]
                }
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom",
            "settings": {
                "domainStrategy": "UseIPv4",
                "redirect": "VPS_B_IP:10000"
            },
            "tag": "direct"
        },
        {
            "protocol": "blackhole",
            "settings": {
                "response": {
                    "type": "http"
                }
            },
            "tag": "block"
        }
    ]
}

VPS B

{
    "log": {
        "access": "",
        "error": "",
        "loglevel": "warning"
    },
    "inbounds": [
    {
      "listen": "0.0.0.0",
      "port": 10000,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "0.0.0.0",
        "port": 10000,
        "network": "tcp",
        "followRedirect": false
      },
      "sniffing": {
        "enabled": false,
        "destOverride": ["http"]
      }
    }
    ],
    "outbounds": [
        {
            "protocol": "freedom"
        }
    ]
}

chika0801 avatar Jul 25 '22 14:07 chika0801

shadowsocks-android or v2rayNG uses VPN service. It function very much like transproxy. All you need to do is disable sniffing or use routeOnly option (xray-core)

Oh yes, I didn't check it. But it will not work with socks/http proxy. As I understand(checked source code) this feature doesn't exist in xray-core right now, so it depends on client protocol. Client should send ip as destination itself.

I think that this feature will be very helpful and makes xray more flexible. We can sniff domain and replace IP, but we can't do the opposite thing.

我参考了这个文章 https://gist.github.com/phlinhng/c11c1268748874982fa6596fb0a4992a 我改了一下配置,但是我没有测试过,你可以自己测试一下

Yes, it should work as I expect because it use "freedom" protocol which has domainStrategy option. But it is very insecure because data will send without any encryption.

mazzz1y avatar Jul 25 '22 15:07 mazzz1y

此功能很实用, 最近碰到的以下情况同样需要此功能:

  1. 内置DNS中自定义域名映射
"dns": {
    "hosts": {
      "domain:abc.com": "x.x.x.x"
    }
  }
  1. 使用socks类型inbound接收需要代理的流量
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 1080,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "routeOnly": true,
        "destOverride": [
          "http",
          "quic",
          "tls"
        ]
      },
      "tag": "socks"
    }
  1. 浏览器SwitchyOmega插件使用socks5协议把abc.com的流量发送到socks类型的inbound.
  2. xray socks inbound接收到流量后无论如何配置最终都会把domain连接类型的流量(abc.com)转发到远程服务端.
  3. 远程服务器端xray中无法解析abc.com对应的IP地址导致连接不成功(因为abc.com对应的IP是在客户端内置DNS中配置的).

这个问题是由于客户端内置DNS中的自定义hosts和服务器端的DNS没有任何相关性导致的, 解决办法目前也只能在服务器端操作系统/etc/hosts中同样添加上客户端的自定义hosts内容, 但操作系统hosts文件功能十分有限并不支持通配符配置方式,每个子域名都需要逐条添加十分繁琐.

如果Xray能提供类似: outbound出站时允许通过参数配置是否改写“连接域名”的流量为“连接IP”的流量,则此问题会被完美解决.

目前Xray内置DNS仅用作域名到IP的解析, 但并没有任何参数(vless/vmess/socks等协议)可以实现根据内置DNS解析结果改写“连接域名流量“为”连接IP流量“这种功能.

目前如果入站接收的流量为连接域名流量(Chrome SwitchyOmega),然后域名对应的IP是在内置DNS的hosts配置的,然后经过嗅探/路由等步骤后,转发到服务器端,服务器端无法解析域名代理失败.

如果能根据内置DNS解析结果改写domain连接类型出站流量为IP连接类型出站流量的功能就太好了,这样在客户端内置DNS的hosts中随意制定规则也不需要同步修改服务端操作系统hosts文件了, 很多的时候服务端都是别人提供自己无法进行修改的.

gubiao avatar Jul 25 '22 16:07 gubiao

别用 switchyomega 尝试 https://tachyondevel.medium.com/%E6%95%99%E7%A8%8B-%E5%9C%A8-windows-%E4%B8%8A%E4%BD%BF%E7%94%A8-tun2socks-%E8%BF%9B%E8%A1%8C%E5%85%A8%E5%B1%80%E4%BB%A3%E7%90%86-aa51869dd0d

yuhan6665 avatar Jul 25 '22 16:07 yuhan6665

别用 switchyomega 尝试 https://tachyondevel.medium.com/%E6%95%99%E7%A8%8B-%E5%9C%A8-windows-%E4%B8%8A%E4%BD%BF%E7%94%A8-tun2socks-%E8%BF%9B%E8%A1%8C%E5%85%A8%E5%B1%80%E4%BB%A3%E7%90%86-aa51869dd0d

目前我的妥协方式是proxifier全局代理拦截所有流量, 然后客户端操作系统DNS直接设置为Xray的内置DNS地址, 这样就可以保证流量先由proxifier拦截,然后使用操作系统DNS(配置了自定hosts映射的Xray内置DNS)解析自定义hosts,然后流量变更为"连接IP流量"发送给xray的socks inbound.

但这种方式引入了额外的组件, 维护繁琐, 相当于流量转换是在xray外部完成的.

gubiao avatar Jul 25 '22 16:07 gubiao

别用 switchyomega 尝试 https://tachyondevel.medium.com/%E6%95%99%E7%A8%8B-%E5%9C%A8-windows-%E4%B8%8A%E4%BD%BF%E7%94%A8-tun2socks-%E8%BF%9B%E8%A1%8C%E5%85%A8%E5%B1%80%E4%BB%A3%E7%90%86-aa51869dd0d

Switchyomega is only one of thousand possible scenarios of using socks-proxy. Also using IPOnDemand routing with Socks proxy causing double-request to DNS(one to internal dns and second to remote dns on outbound node)

mazzz1y avatar Jul 25 '22 18:07 mazzz1y

wow, this feature was already implemented in https://github.com/SagerNet/v2ray-core and works perfectly

{
  "outbounds": [
    {
      "protocol": "shadowsocks",
      "settings": {
        ...
      },
      "domainStrategy": "AsIs/UseIP/UseIPv[4/6]/PreferIPv[4/6]"
    }
  ]
}

mazzz1y avatar Jul 27 '22 10:07 mazzz1y

我想起来了 1.5.1 之后有 根据 DNS Host 重置当前连接的目标地址 https://github.com/XTLS/Xray-core/commit/27224868aba63db8180ee2f2db71aa995930a74d @nekohasekai @gubiao 所说的情况地址应该是IP吧?

yuhan6665 avatar Jul 27 '22 14:07 yuhan6665

我想起来了 1.5.1 之后有 根据 DNS Host 重置当前连接的目标地址 2722486 @nekohasekai @gubiao 所说的情况地址应该是IP吧?

目前最新版Xray, 服务器端开debug日志看连接的是一直都是域名, 如果客户端经过proxifier+操作系统DNS指向Xray内置DNS处理后服务端debug日志看连接的是客户端内置DNS中hosts配置项中自定义的IP.

2722486中的处理过程好像是: 连接IP流量入站->嗅探出域名->发现该域名已经重新定义了hosts->改写连接IP入站流量为hosts中指向的新IP.
如果是这样的处理方式那么对“连接domain的入站流量应该是无效的, 因为这些针对domain的流量并没有经过sniffer.

gubiao avatar Jul 28 '22 03:07 gubiao

重新查看了一遍最新官方文档, 找到了此问题的解决办法:

  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {
        "domainStrategy": "UseIPv4"
      },
      "proxySettings": {
        "tag": "proxy"
      },
      "tag": "ip-to-proxy"
    },
    {
      "protocol": "vless",
        ......
      "tag": "proxy"
    },
    ...
  ]

默认出站修改为freedom, 通过domainStrategy转换“连接domain流量"为"连接IP流量", 然后再通过“proxySettings”把转换后流量发送给最终的proxy出站.

使用这种方式后服务端接收到的所有流量都是"连接IP流量", 也就是说所有DNS解析工作全部由客户端完成了, 服务端如果想针对域名做路由控制只能开启“流量探测”才行.

如果路由组件能提供一种自定义hosts域名匹配器, 则客户端路有中只针对自定义hosts的域名做这种流量重写就完美了.

gubiao avatar Jul 29 '22 16:07 gubiao

@gubiao thank you, it works as I expected

but in my opinion it looks not good and better to add domainStrategy to vless and other outbounds as it is in v2ray from @nekohasekai

in any way I resolved my problem

mazzz1y avatar Jul 30 '22 09:07 mazzz1y

这个问题我在手机端没复现。因为本地开启routeonly之后就是依赖于本地解析,那么服务端收到的来自Android客户端socks5出站全是IP,而Windows不支持SOCKS5,所以除了IP直连的之外均以HTTP域名显现。

Extreme-Icer avatar Feb 04 '23 14:02 Extreme-Icer