Built-in DNS Server

DNS Server

The DNS module built into Xray has two main purposes:

  • During the routing phase, it resolves domain names to IP addresses and performs traffic splitting based on the results of domain name resolution and the value of domainStrategy in the routing configuration module. The built-in DNS server is only used for DNS queries when either of the following values is set:
    • "IPIfNonMatch": When a domain name is requested, it first tries to match it against the domain entries in the routing configuration. If no match is found, the built-in DNS server is used to perform a DNS query for the domain name, and the returned IP address is used to perform IP routing matching again.
    • "IPOnDemand": When a domain name is matched against any IP-based rule, it is immediately resolved to an IP address for matching.
  • It resolves the target address for connection.
    • In the freedom outbound setting, if domainStrategy is set to UseIP, requests made through the outbound proxy will first resolve the domain name to an IP address using the built-in server before making the connection.
    • In the sockopt setting, if domainStrategy is set to UseIP, system connections initiated through the outbound proxy will first be resolved to an IP address using the built-in server before making the connection.

TIP 1

DNS queries sent by the built-in DNS server are automatically forwarded based on the routing configuration.

TIP 2

Only basic IP queries (A and AAAA records) are supported. CNAME records will be queried repeatedly until an A/AAAA record is returned. Other queries will not enter the built-in DNS server.

DNS Processing Flow

If the domain name to be queried:

  • Matches the mapping of "domain name - IP" or "domain name - IP array" in the hosts, then the IP or IP array will be returned as the DNS resolution result.

  • Matches the mapping of "domain name - domain name" in the hosts, then the value of this mapping (another domain name) will be used as the domain name to be queried, and enter the DNS processing flow until an IP is resolved and returned, or an empty resolution is returned.

  • Does not match hosts, but matches the domains list in one or more DNS servers, then according to the priority of the matching rule, use the DNS server corresponding to the rule to perform the query in sequence. If the DNS server that is hit fails to query or expectIPs does not match, then use the next hit DNS server to perform the query. Otherwise, return the resolved IP. If all hit DNS servers fail to query or expectIPs does not match, then the DNS component:

    • By default, it will perform "DNS fallback query": use the "DNS server that has not been used in the last failed query and has a default value of false for skipFallback" to perform the query in sequence. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.
    • If disableFallback is set to true, "DNS fallback query" will not be performed.
  • If neither hosts nor the domains list in DNS servers matches, then:

    • By default, use the "DNS server that has a default value of false for skipFallback" to perform the query in sequence. If the first selected DNS server fails to query or expectIPs does not match, then use the next selected DNS server to perform the query. Otherwise, return the resolved IP. If all selected DNS servers fail to query or expectIPs does not match, return an empty resolution.
    • If the number of "DNS servers that have a default value of false for skipFallback" is 0 or disableFallback is set to true, use the first DNS server in the DNS configuration to perform the query. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.

DnsObject

DnsObject corresponds to the dns section in the configuration file.

{
  "dns": {
    "hosts": {
      "baidu.com": "127.0.0.1",
      "dns.google": ["8.8.8.8", "8.8.4.4"]
    },
    "servers": [
      "8.8.8.8",
      "8.8.4.4",
      {
        "address": "1.2.3.4",
        "port": 5353,
        "domains": ["domain:xray.com"],
        "expectIPs": ["geoip:cn"],
        "skipFallback": false,
        "clientIP": "1.2.3.4"
      },
      {
        "address": "https://1.1.1.1/dns-query",
        "domains": [
          "geosite:netflix"
        ],
        "skipFallback": true,
        "queryStrategy": "UseIPv4"
      },
      {
        "address": "https://1.1.1.1/dns-query",
        "domains": [
          "geosite:openai"
        ],
        "skipFallback": true,
        "queryStrategy": "UseIPv6"
      },
      "localhost"
    ],
    "clientIp": "1.2.3.4",
    "queryStrategy": "UseIP",
    "disableCache": false,
    "disableFallback": false,
    "disableFallbackIfMatch": false,
    "tag": "dns_inbound"
  }
}

hosts: map{string: address} | map{string: [address]}

A list of static IP addresses, with values consisting of a series of "domain": "address" or "domain": ["address 1","address 2"]. The address can be an IP or a domain name. When resolving a domain name, if the domain name matches an item in this list:

  • If the address of the item is an IP, the resolution result will be that IP.
  • If the address of the item is a domain name, this domain name will be used for IP resolution instead of the original domain name.
  • If multiple IPs and domain names are set in the address, only the first domain name will be returned, and the rest of the IPs and domain names will be ignored.

The domain name can take several forms:

  • Plain string: When this string matches the target domain name exactly, the rule takes effect. For example, "xray.com" matches "xray.com" but not "www.xray.com".
  • Regular expression: Starting with "regexp:", the rest is a regular expression. When this regular expression matches the target domain name, the rule takes effect. For example, "regexp:\\.goo.*\\.com$" matches "www.google.com" and "fonts.googleapis.com", but not "google.com".
  • Subdomain (recommended): Starting with "domain:", the rest is a domain name. When this domain name is the target domain name or its subdomain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
  • Substring: Starting with "keyword:", the rest is a string. When this string matches any part of the target domain name, the rule takes effect. For example, "keyword:sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
  • Predefined domain name list: Starting with "geosite:", the rest is a name, such as geosite:google or geosite:cn. The names and domain name lists are listed in Predefined Domain Name Lists.

servers: [string | ServerObject ]

A list of DNS servers that supports two types: DNS addresses (in string format) and ServerObject.

When the value is "localhost", it means to use the default DNS configuration on the local machine.

When the value is a DNS "IP:Port" address, such as "8.8.8.8:53", Xray will use the specified UDP port of this address for DNS queries. The query follows the routing rules. When the port is not specified, the default port 53 is used.

When the value is in the form of "tcp://host:port", such as "tcp://8.8.8.8:53", Xray will use DNS over TCP for queries. The query follows the routing rules. When the port is not specified, the default port 53 is used.

When the value is in the form of "tcp+local://host:port", such as "tcp+local://8.8.8.8:53", Xray will use TCP local mode (TCPL) for queries. That is, DNS requests will not pass through the routing component and will directly request outbound through Freedom, to reduce latency. When the port is not specified, the default port 53 is used.

When the value is in the form of "https://host:port/dns-query", such as "https://dns.google/dns-query", Xray will use DNS over HTTPS (RFC8484, abbreviated as DOH) for queries. Some service providers have certificates with IP aliases, which can be directly written in IP form, such as https://1.1.1.1/dns-query. Non-standard ports and paths can also be used, such as "https://a.b.c.d:8443/my-dns-query".

When the value is in the form of "https+local://host:port/dns-query", such as "https+local://dns.google/dns-query", Xray will use DOH local mode (DOHL) for queries. That is, DOH requests will not pass through the routing component and will directly request outbound through Freedom, to reduce latency. This is generally suitable for use on the server side. Non-standard ports and paths can also be used.

When the value is in the form of "quic+local://host", such as "quic+local://dns.adguard.com", Xray will use DNS over QUIC local mode (DOQL) for queries. That is, DNS requests will not pass through the routing component and will directly request outbound through Freedom. This method requires DNS server support for DNS over QUIC. The default port 784 is used for queries, and non-standard ports can also be used.

When the value is fakedns, the FakeDNS function will be used for queries.

TIP 1

When using localhost, DNS requests on the local machine are not controlled by Xray and additional configuration is required to make DNS requests forwarded by Xray.

TIP 2

DNS clients initialized with different rules will be reflected in the Xray startup log at the info level, such as local DOH, remote DOH, and udp modes.

TIP 3

(v1.4.0+) DNS query logging can be enabled in the log.

clientIp: string

Used to notify the server of the specified IP location during DNS queries. Cannot be a private address.

TIP 1

EDNS Client Subnet support is required for the DNS server.

TIP 2

You can specify clientIp for all DNS servers in DnsObject, or specify it for each DNS server in the configuration of ServerObject (which has higher priority than the configuration in DnsObject).

queryStrategy: "UseIP" | "UseIPv4" | "UseIPv6"

UseIPv4 only queries A records; UseIPv6 only queries AAAA records. The default value is UseIP, which queries both A and AAAA records.

Xray-core v1.8.6 New feature: queryStrategy can be set separately for each DNS server.

    "dns": {
        "servers": [
            "https://1.1.1.1/dns-query",
            {
                "address": "https://1.1.1.1/dns-query",
                "domains": [
                    "geosite:netflix"
                ],
                "skipFallback": true,
                "queryStrategy": "UseIPv4" // geosite:netflix's domain name uses "UseIPv4"
            },
            {
                "address": "https://1.1.1.1/dns-query",
                "domains": [
                    "geosite:openai"
                ],
                "skipFallback": true,
                "queryStrategy": "UseIPv6" // The domain name geosite:openai uses "UseIPv6".
            }
        ],
        "queryStrategy": "UseIP" // Global use of "UseIP"
    }

NOTE:
When the "queryStrategy" value in the child item conflicts with the global "queryStrategy" value, the query for the child item will respond null.

    "dns": {
        "servers": [
            "https://1.1.1.1/dns-query",
            {
                "address": "https://8.8.8.8/dns-query",
                "domains": [
                    "geosite:netflix"
                ],
                "skipFallback": true,
                "queryStrategy": "UseIPv6" // "UseIPv6" conflicts with "UseIPv4".
            }
        ],
        "queryStrategy": "UseIPv4"
    }

Subterm geosite:netflix query gets null response due to conflicting "queryStrategy" values. geosite:netflix domain is queried by global DNS https://1.1.1.1/dns-query and gets A record.

disableCache: true | false

true disables DNS caching, default is false which means caching is not disabled.

disableFallback: true | false

true disables fallback DNS queries, default is false which means fallback queries are not disabled.

disableFallbackIfMatch: true | false

true disables fallback DNS queries when the matching domain list of the DNS server is hit, default is false which means fallback queries are not disabled.

tag: string

Traffic generated by built-in DNS, except for localhost, fakedns, TCPL, DOHL, and DOQL modes, can be matched with inboundTag in routing using this identifier.

ServerObject

{
  "address": "1.2.3.4",
  "port": 5353,
  "domains": ["domain:xray.com"],
  "expectIPs": ["geoip:cn"],
  "skipFallback": false,
  "clientIP": "1.2.3.4"
}

address: address

A list of DNS servers, which can be either DNS addresses (in string form) or ServerObjects.

When the value is "localhost", it means using the local DNS configuration.

When the value is a DNS "IP" address, such as "8.8.8.8", Xray will use the specified UDP port of this address for DNS queries. The query follows routing rules. By default, port 53 is used.

When the value is in the form of "tcp://host", such as "tcp://8.8.8.8", Xray will use DNS over TCP for the query. The query follows routing rules. By default, port 53 is used.

When the value is in the form of "tcp+local://host", such as "tcp+local://8.8.8.8", Xray will use TCP local mode (TCPL) for the query. That is, the DNS request will not go through the routing component and will be sent directly through the Freedom outbound to reduce latency. When no port is specified, port 53 is used by default.

When the value is in the form of "https://host:port/dns-query", such as "https://dns.google/dns-query", Xray will use DNS over HTTPS (RFC8484, abbreviated as DOH) for the query. Some service providers have IP alias certificates, which can be directly written in IP form, such as https://1.1.1.1/dns-query. Non-standard ports and paths can also be used, such as "https://a.b.c.d:8443/my-dns-query".

When the value is in the form of "https+local://host:port/dns-query", such as "https+local://dns.google/dns-query", Xray will use DOH local mode (DOHL) for the query, which means that the DOH request will not go through the routing component and will be sent directly through the Freedom outbound to reduce latency. This is generally suitable for server-side use. Non-standard ports and paths can also be used.

When the value is in the form of "quic+local://host:port", such as "quic+local://dns.adguard.com", Xray will use DOQ local mode (DOQL) for the query, which means that the DNS request will not go through the routing component and will be sent directly through the Freedom outbound. This method requires DNS server support for DNS over QUIC. By default, port 784 is used for the query, and non-standard ports can be used.

When the value is fakedns, FakeDNS functionality will be used for the query.

port: number

The port number of the DNS server, such as 53. If not specified, the default is 53. This item is not applicable when using DOH, DOHL, or DOQL modes, and non-standard ports should be specified in the URL.

domains: [string]

A list of domain names. The domain names in this list will be queried using this server first. The format of domain names is the same as in routing configuration.

expectIPs: [string]

A list of IP ranges in the same format as in routing configuration.

When this item is configured, Xray DNS will verify the returned IP addresses and only return addresses that are included in the expectIPs list.

If this item is not configured, the IP address will be returned as is.

skipFallback: true | false

true means to skip this server when performing DNS fallback queries, and the default is false, which means not to skip.