Modern Linux systems increasingly rely on systemd-resolved
for managing network name resolution. This service, detailed in the systemd-resolved.service(8) man page, offers sophisticated capabilities, including the crucial ability to configure DNS settings on a per-interface basis. This means you can direct DNS queries for one network interface (e.g., a corporate VPN) to specific internal DNS servers, while another interface (e.g., your primary Ethernet) uses different, public DNS servers. This level of control is essential for developers, system administrators, and anyone dealing with complex network environments, multiple network connections, or specific privacy requirements.
This article provides an in-depth, practical guide to configuring systemd-resolved
to use specific DNS servers for individual network interfaces on Linux. We’ll explore methods using systemd-networkd
, NetworkManager, and the resolvectl
utility, complete with actionable code examples and troubleshooting advice.
Understanding systemd-resolved
and Per-Interface DNS
systemd-resolved
acts as a central DNS stub resolver for local applications. It manages /etc/resolv.conf
(ideally by having it symlinked to /run/systemd/resolve/stub-resolv.conf
, which points to systemd-resolved
’s own stub listener at 127.0.0.53
) and provides features like caching, DNSSEC validation, and, importantly, per-link DNS configuration. For more on the traditional resolver configuration, see the resolv.conf(5) man page.
When per-interface DNS servers are defined, systemd-resolved
prioritizes them for queries associated with that specific interface. This association can be based on the source interface of a query or, more powerfully, through “routing domains.”
Key Concepts:
- Global DNS: Fallback DNS servers used if no per-interface configuration applies. Typically set in
/etc/systemd/resolved.conf
, as described in resolved.conf(5). - Per-Link DNS: DNS servers assigned to a specific network interface (e.g.,
eth0
,wlan0
,tun0
). - Routing Domains: Specified with the
Domains=
setting.Domains=example.com
: Makesexample.com
a search domain and routes queries for*.example.com
to this interface’s DNS.Domains=~example.com
: Routes queries for*.example.com
to this interface’s DNS without making it a search domain (routing-only).Domains=~.
: A powerful setting that routes all queries not matching a more specific routing domain on another interface through this interface’s assigned DNS servers. This effectively makes the interface’s DNS primary for general resolution when active.
Method 1: Using systemd-networkd
If you manage your network interfaces with systemd-networkd
(see systemd-networkd.service(8)), configuring per-interface DNS is straightforward and integrated. You define these settings within .network
files located in /etc/systemd/network/
, as specified in the systemd.network(5) man page.
Configuration Steps:
Identify or Create a
.network
File: Each interface managed bysystemd-networkd
needs a corresponding.network
file. For an interface namedeth1
, you might create/etc/systemd/network/10-eth1.network
. The[Match]
section identifies the interface.Add DNS Settings in the
[Network]
Section:DNS=
: A space-separated list of IP addresses for your desired DNS servers.Domains=
: Define search or routing domains.
Example: Configuring eth1
for Internal DNS
Let’s say eth1
connects to a private network requiring specific DNS servers (10.0.0.53
, 10.0.0.54
) for the internal.corp
domain and as general resolvers for traffic through this interface.
Create or edit /etc/systemd/network/10-eth1.network
:
|
|
Explanation:
DNS=10.0.0.53 10.0.0.54
: Sets the specific DNS servers foreth1
.Domains=~internal.corp ~.
:~internal.corp
: Routes all queries for*.internal.corp
to10.0.0.53
and10.0.0.54
.~.
: Makes these DNS servers the default for any other queries originating from or routed througheth1
, if no other more specific domain match is found on other interfaces.
UseDNS=false
: If this interface gets its IP via DHCP, this prevents DHCP-supplied DNS servers from being used bysystemd-networkd
for this interface, ensuring your manually specifiedDNS=
servers are authoritative.
Applying and Verifying systemd-networkd
Changes
Apply Configuration: Restart
systemd-networkd
or reload its configuration:1
sudo systemctl restart systemd-networkd
If the interface was already up, you might need to bring it down and up, or re-evaluate its configuration:
1 2 3
sudo networkctl reconfigure eth1 # or if using older methods to bring interfaces up/down: # sudo ifdown eth1 && sudo ifup eth1
Verify with
resolvectl
: Check the DNS settings for the interface using the resolvectl(1) man page as reference:1
resolvectl status eth1
This should list
10.0.0.53
and10.0.0.54
as current DNS servers foreth1
and show the configured domains.Test a query:
1 2 3 4 5 6
# This query should go through eth1's DNS servers resolvectl query host.internal.corp # This query should also use eth1's DNS if eth1 is preferred for # general resolution due to the "~." domain. resolvectl query -i eth1 example.com
Method 2: Using NetworkManager
NetworkManager is a popular dynamic network control and configuration system that also works closely with systemd-resolved
. You can learn more about it from the NetworkManager official website. Per-interface DNS settings are configured through its connection profiles, typically using nmcli
(command-line utility, see nmcli(1) man page) or graphical tools like nm-connection-editor
.
Configuration Steps with nmcli
:
Identify the Connection Name: List your NetworkManager connections:
1
nmcli connection show
Find the name of the connection profile associated with the interface you want to configure (e.g., “Wired connection 1”, “MyVPN”).
Modify DNS Settings: Use
nmcli connection modify
to set DNS servers and search/routing domains. You’ll likely also want to tell NetworkManager to ignore automatically configured (e.g., DHCP-provided) DNS servers for this connection.
Example: Configuring “MyOfficeVPN” Connection
Suppose you have a VPN connection profile named “MyOfficeVPN” and want it to use DNS servers 192.168.1.10
and 192.168.1.11
for the domain office.example.net
and for all other traffic routed via this VPN.
|
|
Important: The ipv4.dns-search
property when used with systemd-resolved
can take the ~domain
syntax for routing domains.
Applying and Verifying NetworkManager Changes
Apply Configuration: Reactivate the connection for the changes to take effect:
1 2
nmcli connection down MyOfficeVPN nmcli connection up MyOfficeVPN
Alternatively, for some settings, a reload might be sufficient:
1 2
nmcli connection reload MyOfficeVPN # Followed by re-activating if needed
Verify with
resolvectl
: After the connection is active, check its DNS status:1 2
# Replace 'vpn0' with the actual interface name for MyOfficeVPN resolvectl status vpn0
Test a query:
1
resolvectl query payroll.office.example.net
Method 3: Using resolvectl
(Dynamic/Temporary Configuration)
The resolvectl
command-line utility can directly set per-interface DNS settings. However, these settings are typically not persistent across reboots or interface restarts unless a script or service re-applies them. This method is useful for testing, temporary configurations, or scripting.
Configuration Commands:
resolvectl dns <interface> <server1> [server2] ...
: Sets DNS servers for<interface>
.resolvectl domain <interface> <domain1> [domain2] ...
: Sets search/routing domains for<interface>
. Use~.
for routing all traffic.resolvectl revert <interface>
: Clears manually set DNS settings for<interface>
, reverting to settings provided by other managers (like NetworkManager orsystemd-networkd
) or DHCP.
Example: Temporarily Setting DNS for wlan0
To temporarily set wlan0
to use 9.9.9.9
and route all its DNS queries through it:
|
|
This shows 9.9.9.9
as the current server and ~.
as the domain.
To test:
|
|
To revert wlan0
to its previous configuration (e.g., managed by NetworkManager):
|
|
Verifying Your Overall DNS Configuration
Regardless of the method used, these tools are crucial for verification:
resolvectl status [interface]
: Your primary tool. Without an interface argument, it shows global status and all link statuses. With an interface name (e.g.,resolvectl status eth0
), it shows detailed DNS information for that specific link, including current DNS servers, DNSSEC status, and configured domains.resolvectl query [--interface=<IFACE>] <hostname>
: Performs a DNS query. Use--interface
to test resolution via a specific interface’s settings.cat /etc/resolv.conf
: Check its contents. Forsystemd-resolved
to function optimally with its stub listener, this file should typically be a symlink to/run/systemd/resolve/stub-resolv.conf
and containnameserver 127.0.0.53
.1 2 3
ls -l /etc/resolv.conf # Example output: # /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
journalctl -u systemd-resolved -f
: Follow the live logs forsystemd-resolved
for troubleshooting. For more detail, you can temporarily increase its log level.
Key Global Configuration: /etc/systemd/resolved.conf
While this article focuses on per-interface DNS, it’s useful to know that global fallback DNS settings are configured in /etc/systemd/resolved.conf
or via drop-in files in /etc/systemd/resolved.conf.d/
. Refer to the resolved.conf(5) man page for all options.
An example /etc/systemd/resolved.conf.d/global-dns.conf
might look like:
|
|
These global settings are used if a query doesn’t match any specific per-interface routing rules or if the matched interface has no DNS servers defined.
Common Challenges and Troubleshooting
/etc/resolv.conf
Mismanagement: Directly editing/etc/resolv.conf
when it’s managed bysystemd-resolved
will lead to lost changes. Ensure it’s correctly symlinked.- Conflicting Network Managers: If both
systemd-networkd
and NetworkManager are active, they might compete to configure the same interface. It’s generally best to let only one manage a particular interface’s network settings. - DHCP Overwrites:
- For
systemd-networkd
: In the.network
file’s[DHCPv4]
or[DHCPv6]
section, ensureUseDNS=false
if you want to ignore DHCP-provided DNS servers in favor of manually specified ones. - For NetworkManager: Use
nmcli connection modify <conn_name> ipv4.ignore-auto-dns yes
(and similarly foripv6
).
- For
- Caching:
systemd-resolved
caches responses. If you’re not seeing updated results immediately after a change, flush the caches:1
sudo resolvectl flush-caches
- Order of
Domains=
Entries: The order can matter, especially if you have overlapping domains or a mix of search and routing domains on the same interface. More specific routing domains are generally preferred. - Understanding
~.
Behavior:Domains=~.
on an interface makes its DNS servers handle all queries not explicitly routed elsewhere. If multiple active interfaces have~.
,systemd-resolved
uses metrics and interface states to pick one, which can sometimes be non-obvious. Be deliberate when using~.
.
Advanced Topics: DNS-over-TLS (DoT) and DNSSEC
systemd-resolved
also supports DNS-over-TLS (DoT) and DNSSEC validation, which can be configured globally in resolved.conf
or, importantly, on a per-interface basis. This allows you, for instance, to enforce DoT for a specific Wi-Fi connection that routes to a public DoT-enabled resolver.
- DoT: Set
DNSOverTLS=yes
(enforce) orDNSOverTLS=opportunistic
in the[Resolve]
section ofresolved.conf
or the[Network]
section of a.network
file. - DNSSEC: Set
DNSSEC=yes
(validate and fail if invalid),DNSSEC=no
, orDNSSEC=allow-downgrade
(validate if possible, otherwise accept).
These settings enhance security and privacy and can be tailored to the trust level of the network each interface connects to. The Arch Wiki page on systemd-resolved often contains practical tips on these advanced features.
Conclusion
Configuring per-interface DNS servers with systemd-resolved
offers a powerful way to manage network name resolution on modern Linux systems. Whether you use systemd-networkd
for static server-like configurations, NetworkManager for dynamic client setups, or resolvectl
for quick tests, systemd-resolved
provides the underlying framework for fine-grained control.
By understanding how to define DNS servers and routing domains for each network link, you can ensure that applications use the correct resolvers for specific corporate networks, VPNs, or privacy-enhancing services, making your Linux system more flexible, secure, and adaptable to diverse networking environments. Remember to always verify your changes using resolvectl status
and resolvectl query
to ensure your DNS resolution behaves as intended.