Routing and DNS
Routing decides what happens to each connection that reaches a node: which Outbound carries it, or whether it is blocked. DNS decides how the node resolves names. Both are part of a Template, on its Routing and DNS tabs, so every node on the template routes the same way.
How routing works
The node checks the rules from top to bottom for every new connection. The first rule that matches decides. A connection that matches no rule goes to the Final outbound.
With no rules at all, everything goes to the final outbound, which is the built-in direct unless you choose another. That is a sensible start: add rules only for traffic that should go somewhere else.
Writing rules
On the template's Routing tab:
- Under Rule sets, select the lists your rules will match on. Only selected rule sets can be named by a rule. See Rule sets.
- Click Add rule.
- Under Match, set what the rule matches.
- Choose the Action, and for
routethe Outbound. - Save the rule, then save the template.
The list numbers the rules in the order the node checks them. A new rule is added at the end; to change the order, move it on the JSON tab.
What a rule can match
A rule can combine several matchers. All of them must match, unless you tick Invert match.
| Matcher | Matches |
|---|---|
| Domain, Domain suffix, Domain keyword, Domain regex | The destination's name |
| IP CIDR, IP is private, IP version | The destination's address |
| Port, Port range | The destination's port |
| Rule set | Any list the template selected; Rule set matches source IP matches the user's address against it instead |
| Network | tcp or udp |
| Protocol | What sniffing detected: tls, http, quic, dns, bittorrent and others |
| Inbound | The inbound tag the connection came in on |
| Auth user (panel user) | The user's account name |
| Source IP CIDR, Source port, Source IP is private | Where the connection comes from |
Rules about things only a phone or desktop app can see, such as the app's process or the Wi-Fi network, are refused when you save: a node never sees them, so such a rule would never match.
Actions
| Action | Effect |
|---|---|
route | Sends the connection to the chosen outbound. |
reject | Refuses the connection. |
sniff | Reads the start of the connection to detect its protocol and domain, then goes on to the next rule. |
resolve | Looks up the domain, so later address rules can match it. |
hijack-dns | Answers the connection as a DNS query with the node's own DNS. |
route-options | Sets connection options without choosing an outbound. |
Protocol sniffing
Many connections arrive with an address and no name. A sniff rule reads the TLS server name or HTTP host, and the protocol, from the start of the connection. Rules after it can then match by domain and by Protocol. Put the sniff rule first when later rules match domains or protocols.
Sniffing is detection, not a guarantee: traffic it does not recognise passes on to the next rule unmatched.
The final outbound
Final outbound takes every connection no rule matched. It is the default for the nodes on the template. Two things override it on a single node: a node's own routing (below), and a node that relays exactly one Tunnel, which takes that tunnel as its final.
When the form is not enough
The JSON tab shows the whole routing block exactly as nodes receive it. Write a shape the form does not offer there. The panel still refuses options that would make a node reject the configuration.
DNS
The template's DNS tab sets the resolvers the node uses for its own lookups: for resolve rules, for outbounds that dial a server by name, and for hijack-dns.
Add servers with Add server and pick a type: plain UDP or TCP, encrypted tls, https, quic or h3, the node's own system resolver (local), its hosts file (hosts), dhcp, or fakeip. A server can send its queries through an outbound with Detour (outbound). DNS rules, below the servers, send chosen names to chosen servers.
When a template defines more than one DNS server, set a Default domain resolver on the Routing tab. Without one, a node cannot resolve the names of outbound servers and refuses the whole configuration. The editor warns you when it is missing.
Presets
From a preset, on the Routing and DNS tabs, applies a ready block. See Templates for the list.
- A routing preset replaces the template's rules, because rule order is the routing. Block torrents is the exception and is added in front of your rules. The rule sets a preset needs are added to the selection.
- A DNS preset replaces the DNS block with Cloudflare, Google, Quad9 or AdGuard over DNS-over-TLS, or the node's system resolver.
Lists a preset needs
A preset is only as good as its lists. If the panel has no copy of a list the preset uses, the panel would leave out that list and every rule matching on it, and the preset would quietly do nothing. So the dialog checks first:
- a list you do not have yet is named, and Add the lists and apply downloads it first;
- a list the panel lists but holds no copy of is named, and you fix it on the Rule sets page first;
- a list the catalogue gives no source for is refused outright.
Blocking torrents
Block torrents adds a sniff rule and sends what looks like BitTorrent to a block outbound named block-torrent. The node counts what it blocks: the figure is on the node's row and in the panel's metrics, and above a rate you set it raises a node.rejections_high Event.
It is best effort. Sniffing recognises the BitTorrent handshake, and clients that encrypt it, which most do by default, pass. Read the counter as what was caught, not as all there was.
Country presets
Iran + block ads, China + block ads and Russia + block ads send that country's domains and addresses straight out from the node, so domestic traffic does not travel further, and reject the ad list. On a relay this keeps local traffic off the tunnel. The result is as complete as the country lists; if you need fuller coverage, point the catalogue at a fuller list (below).
Your own presets
The presets shelves (rule sets, inbounds, routing and DNS) come from a catalogue the panel serves. You can add to it, or replace entries in it, without waiting for a release:
- Put a
.jsonfile in the presets directory:/var/opt/nexora/presets/on a standard install, or the directory set under Settings → General → Preset catalogue → Catalogue directory. - Open the presets dialog again. No restart is needed.
Every *.json file there is merged onto the built-in catalogue in file-name order. An entry with a new key or tag is added; one with an existing key or tag replaces the built-in one. A file that does not parse is skipped and noted in the panel log, and the settings page shows the files in effect.
For example, a file that adds a country to the rule-set shelf, from a mirror you control:
{
"version": 1,
"ruleSets": {
"countries": [
{
"key": "tr",
"label": "Turkey",
"items": [
{ "tag": "geoip-tr", "url": "https://mirror.example.com/geoip-tr.srs", "label": "IP ranges" }
]
}
]
}
}A country entry replaces the built-in one with the same key as a whole, so to re-point one list of a built-in country, repeat that country's other lists in your entry too. Rule-set services merge by tag; inbound, routing and DNS presets merge by key.
A node's own routing
A node can replace its template's routing with its own. Open the node's Config panel from its row and fill in Routing (per-node override). This beats the template on that node only, including its final outbound. Use it for the one server that must route differently, and keep everything else in the template.
Checking a route
Route test, in the menu of a node's or a user's row, walks the node's own rules for a connection you describe (destination, port, and optionally the sniffed protocol and domain) and names the rule and outbound that take it. Test and connect also opens one real connection from the node down that path. See Nodes.
Related
- Rule sets: the lists rules match on.
- Outbounds: where rules send traffic.
- Templates: where routing and DNS live.
- The path of a packet: the path a connection takes through a node.
