Routing & DNS

Introduction #

FoXray uses local configuration + Xray Json to generate the final configuration file. This move is mainly to enable users to focus on Routing and DNS when writing Xray Json, without paying attention to the implementation of FoXray.

Difference #

FoXray only supports a subset of Xray’s configurations.

Compared with the original Xray configuration, FoXray has the following limitations.

DNS #

  1. servers only supports ServerObject .

  2. Do Not support FakeDNS .

  3. hosts only supports the form of "domain": ["address1","address2"] .

  4. tag is fixed to dnsQuery . Even if you specify tag as something else, it will be fixed to dnsQuery when generating the config file.

Routing #

  1. routing doest Not support custom domainMatcher.

  2. routing doest Not support balancers.

  3. RuleObject doest Not support custom domainMatcher.

  4. RuleObject doest Not support user, attrs, balancerTag.

On and Off #

The basis for FoXray to determine whether to enable Routing or DNS is: whether the Xray Json contains routing or dns field.

If you only want to use Routing, only configure the routing field.

If you only want to use DNS, only configure the dns field.

Note:

  1. If you enable DNS, even if you disable Routing, FoXray will generate two rules to handle DNS queries.

  2. If you disable DNS, FoXray will use 8.8.8.8 as the default DNS.

Rule dataset #

According to experience, when the number of rules included in the routing and DNS configuration reaches tens of thousands, the VPN will most likely fail to start on iOS. FoXray has counted the number of rules under each category in the rule dataset for you, and you can calculate the total number of rules used in the configuration by yourself.

Sniffing #

Starting from version 2.6, FoXray supports custom sniffing.

Notice:

  1. FoXray only parses the sniffing configuration of the first inbound.
{
  "inbounds" : [
    {
      "sniffing" : {
        "destOverride" : [
          "http",
          "tls",
          "quic"
        ],
        "domainsExcluded" : [
          "courier.push.apple.com"
        ],
        "enabled" : true
      }
    }
  ]
}

Full configuration #

{
    "dns": {
        "hosts": {
          "baidu.com": ["127.0.0.1"],
          "dns.google": ["8.8.8.8", "8.8.4.4"]
        },
        "servers": [
            {
                "address": "1.2.3.4",
                "port": 53,
                "domains": [
                    "domain:xray.com",
                    "geosite:cn"
                ],
                "expectIPs": [
                    "geoip:cn"
                ],
                "skipFallback": false
            },
            {
                "address": "localhost"
            }
        ],
        "queryStrategy": "UseIP",
        "disableCache": false,
        "disableFallback": false,
        "disableFallbackIfMatch": false,
        "tag": "dnsQuery"
    },
    "inbounds" : [
      {
        "sniffing" : {
          "destOverride" : [
            "http",
            "tls",
            "quic"
          ],
          "domainsExcluded" : [
            "courier.push.apple.com"
          ],
          "enabled" : true
        }
      }
    ],
    "routing": {
        "domainStrategy": "AsIs",
        "rules": [
            {
                "type": "field",
                "domain": [
                    "baidu.com",
                    "qq.com",
                    "geosite:cn"
                ],
                "ip": [
                    "0.0.0.0/8",
                    "10.0.0.0/8",
                    "fc00::/7",
                    "fe80::/10",
                    "geoip:cn"
                ],
                "port": "53,443,1000-2000",
                "sourcePort": "53,443,1000-2000",
                "network": "tcp",
                "source": [
                    "10.0.0.1",
                    "geoip:cn"
                ],
                "inboundTag": [
                    "tag-vmess"
                ],
                "protocol": [
                    "http",
                    "tls",
                    "bittorrent"
                ],
                "outboundTag": "direct"
            }
        ]
    }
}

Manually written #

How does FoXray convert routing and DNS configuration to Xary Json? #

All conversion relations are as follows:

Default Outbound

{
  "outbounds" : [
    {
      "tag" : "proxy"
    }
  ]
}

ipQuery Outbound

{
  "routing" : {
    "rules" : [
      {
        "inboundTag" : [
          "dnsQuery"
        ],
        "outboundTag" : "proxy",
        "type" : "field"
      }
    ]
  }
}

nonIPQuery

{
  "outbounds" : [
    {
      "protocol" : "dns",
      "settings" : {
        "nonIPQuery" : "skip",
      }
    }
  ]
}

nonIpQuery Outbound

{
  "outbounds" : [
    {
      "protocol" : "dns",
      "streamSettings" : {
        "sockopt" : {
          "dialerProxy" : "proxy"
        }
      }
    }
  ]
}

nonIPQuery DNS

{
  "outbounds" : [
    {
      "protocol" : "dns",
      "settings" : {
        "address" : "8.8.8.8"
      }
    }
  ]
}

Writing #

  1. The first two rules in routing must be of the following form.
{
  "routing" : {
    "rules" : [
      {
        "inboundTag" : [
          "dnsQuery"
        ],
        "outboundTag" : "proxy",
        "type" : "field"
      },
      {
        "outboundTag" : "dnsOut",
        "port" : "53",
        "type" : "field"
      }
    ]
  }
}

Among them, the outboundTag of the first rule represents the ipQuery Outbound. These two rules will be removed when parsing.

Note: In FoXray, you don’t need to write these two rules, the program will automatically generate them.

Example #

{
  "dns" : {
    "servers" : [
      {
        "address" : "8.8.8.8"
      }
    ]
  },
  "outbounds" : [
    {
      "tag" : "proxy"
    },
    {
      "protocol" : "dns",
      "settings" : {
        "address" : "8.8.8.8",
        "nonIPQuery" : "skip",
        "userLevel" : 0
      },
      "streamSettings" : {
        "sockopt" : {
          "dialerProxy" : "proxy"
        }
      },
      "tag" : "dnsOut"
    }
  ],
  "routing" : {
    "rules" : [
      {
        "inboundTag" : [
          "dnsQuery"
        ],
        "outboundTag" : "proxy",
        "type" : "field"
      },
      {
        "outboundTag" : "dnsOut",
        "port" : "53",
        "type" : "field"
      },
      {
        "domain" : [
          "geosite:private",
          "geosite:bing",
          "geosite:cn"
        ],
        "outboundTag" : "direct",
        "type" : "field"
      },
      {
        "ip" : [
          "geoip:private"
        ],
        "outboundTag" : "direct",
        "type" : "field"
      }
    ]
  }
}