· Routing · About 10 min read

V2Ray Routing Rules: Domain and IP Rules for Split Tunneling

Learn how v2rayN domain, IP, geosite, and geoip rules work, with routing examples for bypassing mainland China, proxying all traffic, and setting custom direct connections.

At a glance

For users who have imported a subscription and can connect to a node but want to adjust split tunneling. First confirm that traffic reaches the client, then distinguish what domain and IP rules match, and finally arrange rules in this order: custom exceptions, general categories, and the default route. This guide includes V2Ray/Xray routing snippets, v2rayN steps, and ways to verify the results. Outbound tags in the examples must match your current configuration; these snippets are not complete client configurations.

Before You Start: Traffic Must Reach the Core

Routing rules select an outbound; they do not automatically send every app through the proxy. A browser sends requests to the local proxy port when it follows the system proxy settings. Apps that ignore those settings usually need a proxy configured separately or TUN interception. Enabling TUN does not mean all traffic must use the proxy: once traffic reaches the core, routing rules can still send it direct.

v2rayN is a desktop client, and the active core applies the routing rules. The JSON in this guide uses the V2Ray/Xray routing format and is intended for compatible core configurations; it is not a universal syntax for every core. On Android, v2rayNG uses the Xray core, while v2flyNG uses the v2fly core. Their menus, built-in rules, and resource update methods are not identical.

10808
The examples use a local proxy port; replace it with the actual listening port
53
A common port for traditional DNS; it does not cover all DNS traffic

Domain vs. IP Rules: What They Match and How to Write Them

domain matches the destination domain in a request, while ip matches the destination IP or an IP resolved according to the configured strategy. A domain rule is not a full-URL filter: do not include https://, a page path, or query parameters. Different paths on the same domain generally use the same outbound.

SyntaxWhat it matchesWhen to use it
full:example.comMatches only example.comAdd an exception for a single hostname
domain:example.comMatches the root domain and its subdomainsRoute services under the same domain through the same outbound
exampleMatches domains containing the specified textBroad match; may catch unintended domains, so use with care
geosite:cnReferences the cn category in the domain resourcesRoute using a maintained set of domains
192.168.0.0/16Matches a specified IPv4 subnetSend LAN addresses direct
geoip:cnReferences the cn category in the IP resourcesRoute according to the address set containing the destination IP

For example, domain:example.com can match api.example.com, but it will not treat notexample.com as a subdomain. For precise matching, prefer full: or domain: rather than using a short keyword in place of domain-boundary matching.

Domain Exceptions

Rule field
domain
Match
domain:example.com
Outbound
direct
Recommended position
Before general categories

Useful when you know the exact domain; the example domain is for illustration only.

LAN IP Rules

Rule field
ip
Match
geoip:private
Outbound
direct
What to check
IPv4 and IPv6 ranges

Confirm the resource file includes this category, or enter the appropriate CIDR range for your network.

Rule Order: The First Match Wins

Rules are checked from top to bottom. Once a rule matches, later rules are not checked for a “more specific” match. If a broad rule comes first, custom exceptions below it may never run. Multiple values in the same field array generally work as an OR; different conditions such as domain, IP, and port within one rule must all match together.

If no rule matches, the core generally uses the first outbound in the outbounds array. The final TCP/UDP rules below explicitly send unmatched traffic to the proxy, so “no match” does not accidentally mean direct. This snippet contains only the routing section; direct and proxy must be outbound tags already defined in your complete configuration.

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "domain": ["domain:example.com"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["geosite:cn"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:cn"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

geosite, geoip, and DNS Strategies

geosite is a domain collection, while geoip is an IP address collection. Neither is a live lookup service. Referencing a category that does not exist, or using a missing or incompatible resource file, can prevent the core from loading. Updating a subscription fetches nodes again; it does not necessarily update routing resources.

domainStrategy controls how domain names are handled during routing; it is not a complete DNS server configuration. With IPIfNonMatch, the core may resolve the IP and try matching again only if no domain rule matched. If a catch-all rule at the end has already matched, the “no match” condition is not met.

StrategyRouting behaviorNote
AsIsDoes not actively resolve domain names to IPs during routingDomain requests primarily rely on domain rules; the IP field can still match direct connections to IP addresses
IPIfNonMatchAttempts to resolve and match again when no domain rule matchesA catch-all rule at the end matches first, so you cannot rely on an IP fallback afterward
IPOnDemandAttempts resolution when a rule requiring an IP is reachedRule order affects when resolution is triggered; check that DNS is working too

The geoip:cn rule in the configuration above handles connections made directly to an IP, but a catch-all rule at the end does not guarantee an IP fallback for every uncategorized domain. To classify unmatched domains by their resolved IP, consider IPOnDemand and place domain rules that need priority before IP rules. Alternatively, remove the catch-all and confirm that the first outbound is the proxy.

Three Setups: Bypass Mainland China, Proxy All Traffic, or Add Custom Direct Rules

“Bypass mainland China” usually means sending LAN and domestic destinations direct while proxying everything else. “Proxy all traffic” means sending all traffic that reaches the core through the proxy outbound. Neither setup guarantees that an app's traffic is being intercepted. Check separately for needs such as company networks, printers, and home storage so you do not lose access when switching setups.

SetupRule orderWhat to verify
Bypass mainland ChinaCustom exceptions → direct for LAN → direct for domestic domains/IPs → proxy fallbackDomestic services use direct; other test destinations use the proxy
Proxy all trafficKeep LAN exceptions if needed; send all other TCP/UDP traffic to the proxyCheck for any earlier direct rules and confirm that the app's traffic reaches the core
Custom direct rulesMove the specified full/domain rules to the top, then keep the existing split-tunnel rulesCheck whether the main domain, login domain, and asset domains need separate rules

One main domain may not be enough to send a business site direct. Login, API, and static assets may use different domains. Check the logs for actual requests, then add only the domains you need. Do not set an entire shared CDN address range to direct just for convenience; that can affect unrelated sites.

  1. Save the current setup

    Note the current routing profile name and back up its rules. Confirm that the node works and keep an unmodified copy of the configuration so you can restore it if something goes wrong.

  2. Open routing settings

    In a v2rayN desktop interface that provides this option, go to Settings → Routing Settings. Depending on the version, the option may instead be under Routing on the main screen; use the label shown in your installed build.

  3. Edit the rules

    Select the routing profile you want to use and open the rule editor. Add a domain entry such as domain:example.com and choose direct as the outbound. If the interface has separate fields for the prefix and value, select the rule type and enter the domain in the corresponding fields.

  4. Reorder the rules

    Move exception rules above domestic categories and fallback rules. Add domain and IP rules separately. After saving, enable the profile using the Routing selector on the main screen.

  5. Reconnect and verify

    Wait for the configuration to reload, and restart the core if needed. Close existing browser connections and revisit the site. Check the destination and outbound in the logs for the new connection; existing long-lived connections are not a reliable way to test new rules.

Verify Split Tunneling: Check Ports, Logs, and Outbounds

A page loading only shows that one route works; it does not prove that traffic used the intended outbound. Test one destination that should go direct, one that should use the proxy, and one LAN address. In the logs, check the destination domain or IP, the selected outbound tag, and any error messages. If the log level is too low, raise it temporarily and restore it after testing.

The commands below force requests through a local HTTP proxy. The example assumes an HTTP or mixed inbound listening on 127.0.0.1:10808. Confirm the actual protocol and port in the client first; if the port only provides SOCKS, do not copy the HTTP proxy options. These commands demonstrate how to send a request and do not imply that the target site requires any particular routing policy.

curl --proxy http://127.0.0.1:10808 --connect-timeout 10 --max-time 20 -I https://example.com/

Common Questions About Routing Rules

Why does traffic still use the proxy after I add a domain rule?

First confirm that the rule contains a domain only, without a protocol or path. Then move it above general rules and make sure the profile is active. If the logs show only a destination IP, check whether the app resolved the domain before traffic reached the core and whether the inbound can provide the destination domain.

Do I need to add both geosite:cn and geoip:cn?

There is no syntax requirement to add both, but they match different inputs: the former is useful for known domains, while the latter matches destination IPs or resolved addresses. To cover both, add separate rules and check domainStrategy; adding a category name does not guarantee that DNS resolution will occur.

Will my custom direct rules disappear after I update my subscription?

Node subscriptions and client routing settings are generally managed separately, but importing a complete configuration, restoring settings, or replacing a routing profile can change rules. Back up your custom profile and avoid editing temporary configuration files generated at runtime.

Can I copy desktop rules directly to Android?

You can reuse the same approach to domains, CIDR ranges, and rule priority, but do not copy the entire desktop configuration. Check the resource files, outbound tags, and custom rule menus in v2rayNG and v2flyNG separately. After saving, reconnect and use the logs to verify the actual outbound.

Client downloadsChoose a package for your platform