Rocky 10: split DNS with routing domains
Test scope
Section titled “Test scope”A Rocky Linux 10.2 Server VM with systemd-resolved-257-23.el10_2.1.rocky.0.1 installed from the installation media (it is not part of the Server environment).
Goal: send *.lab.test to the internal resolver (192.168.2.241) and leave everything else on the default path. Screenshot: public/evidence/resolved/rocky-split.png.
Two commands
Section titled “Two commands”sudo resolvectl dns ens18 192.168.2.241sudo resolvectl domain ens18 '~lab.test'The ~ prefix is the whole trick: it declares lab.test as a routing domain, meaning only queries in that domain go to this server.
Without ~, lab.test is merely a search domain used to complete short names — it does not change where queries are sent.
Proving the routing
Section titled “Proving the routing”$ resolvectl query web.lab.testweb.lab.test: 192.168.2.241 -- link: ens18-- Information acquired via protocol DNS in 1.0ms.-- link: ens18 is the proof: the answer came from the link-scoped DNS server.
$ resolvectl status ens18 DNS Servers: 192.168.2.241 DNS Domain: ~lab.testOutside names never go there
Section titled “Outside names never go there”$ resolvectl query example.comexample.com: resolve call failed: Could not resolve 'example.com', server or network returned error: REFUSED (Not Ready)The lab has no upstream, so outside names fail — which is exactly the point: example.com was not sent to 192.168.2.241, otherwise the internal dnsmasq would have answered with its wildcard address (a classic false “poisoning” diagnosis).
In a real network that side points at a public resolver, and both domains coexist on one host.
Making it persistent
Section titled “Making it persistent”resolvectl changes are runtime-only; they are overwritten on restart or nmcli con up. Persist them in the connection:
sudo nmcli connection modify lab-static ipv4.dns 192.168.2.241sudo nmcli connection modify lab-static ipv4.dns-search '~lab.test'sudo nmcli connection up lab-staticresolvectl status ens18 | grep -E 'DNS Servers|DNS Domain'Check that DNS Domain still shows the ~ entry.
Common traps
Section titled “Common traps”- Forgetting
~: the domain becomes a suffix only; - Editing
/etc/resolv.conf: resolved writes that file and ignores your edits; - Trusting a working
resolvectl queryas persistence:nmcli con upresets it; - Verifying split DNS with
dig:digbypasses resolved’s routing and shows something else entirely.
Practice: see the difference ~ makes
Section titled “Practice: see the difference ~ makes”sudo resolvectl domain ens18 'lab.test' # drop the ~resolvectl query web.lab.testsudo resolvectl domain ens18 '~lab.test' # restore itresolvectl query web.lab.testresolvectl status ens18 | grep 'DNS Domain'Checks:
- With
~the answer says-- link: ens18; - Without it,
DNS Domainshows plainlab.testand the query is no longer link-scoped; Current DNS Servermatches your expectation;- Restoring
~brings the split behaviour back.
常见问题
Can I have several routing domains?
Yes — resolvectl domain accepts a list, e.g. `~lab.test ~corp.internal`.
Does /etc/hosts win?
resolved consults hosts first by default (depending on nsswitch.conf), before any DNS query.
Why does dig not show the split?
dig sends packets straight to a chosen server and skips the routing done by resolved; resolvectl query is the correct tool here.
Next steps
Section titled “Next steps”- resolved basics: /en/systemd-resolved/
- dnsmasq server: /en/dnsmasq-lab/
- NetworkManager: /en/network-basics/