Skip to content
Search Rocky Linux

    Browse this documentation

    Rocky 10: split DNS with routing domains

    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.

    Terminal window
    sudo resolvectl dns ens18 192.168.2.241
    sudo 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.

    $ resolvectl query web.lab.test
    web.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.test
    $ resolvectl query example.com
    example.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.

    resolvectl changes are runtime-only; they are overwritten on restart or nmcli con up. Persist them in the connection:

    Terminal window
    sudo nmcli connection modify lab-static ipv4.dns 192.168.2.241
    sudo nmcli connection modify lab-static ipv4.dns-search '~lab.test'
    sudo nmcli connection up lab-static
    resolvectl status ens18 | grep -E 'DNS Servers|DNS Domain'

    Check that DNS Domain still shows the ~ entry.

    • Forgetting ~: the domain becomes a suffix only;
    • Editing /etc/resolv.conf: resolved writes that file and ignores your edits;
    • Trusting a working resolvectl query as persistence: nmcli con up resets it;
    • Verifying split DNS with dig: dig bypasses resolved’s routing and shows something else entirely.
    Terminal window
    sudo resolvectl domain ens18 'lab.test' # drop the ~
    resolvectl query web.lab.test
    sudo resolvectl domain ens18 '~lab.test' # restore it
    resolvectl query web.lab.test
    resolvectl status ens18 | grep 'DNS Domain'

    Checks:

    1. With ~ the answer says -- link: ens18;
    2. Without it, DNS Domain shows plain lab.test and the query is no longer link-scoped;
    3. Current DNS Server matches your expectation;
    4. 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.