When working with Ubuntu 18.04 (especially in VM environments), you might need to add custom DNS servers for local network resolution. The traditional approach of editing /etc/resolv.conf
doesn't work because:
- It's a symlink to
/run/systemd/resolve/stub-resolv.conf
- Changes get overwritten by systemd-resolved on reboot
- The file explicitly warns "This file is managed by man:systemd-resolved(8). Do not edit."
Instead of modifying resolv.conf directly, we should use systemd-resolved's native configuration methods. Here's how to permanently add your local DNS server (192.168.X.Y) and search domain (foo.local):
sudo mkdir -p /etc/systemd/resolved.conf.d
sudo nano /etc/systemd/resolved.conf.d/local-dns.conf
Add this configuration:
[Resolve]
DNS=192.168.X.Y
Domains=foo.local
After saving the file, restart the systemd-resolved service:
sudo systemctl restart systemd-resolved
Verify your configuration with:
systemd-resolve --status
For more granular control (e.g., different DNS servers per network interface), use NetworkManager:
sudo nmcli con mod "Your Connection Name" ipv4.dns "192.168.X.Y"
sudo nmcli con mod "Your Connection Name" ipv4.dns-search "foo.local"
sudo nmcli con up "Your Connection Name"
- Check if your changes took effect:
cat /run/systemd/resolve/resolv.conf
- Test DNS resolution:
resolvectl query hostname.foo.local
- If using DHCP, ensure it's not overwriting your settings
As a last resort (not recommended), you can replace the symlink with a static file:
sudo rm /etc/resolv.conf
sudo nano /etc/resolv.conf
Add your custom configuration:
search foo.local
nameserver 192.168.X.Y
options edns0
Then make it immutable:
sudo chattr +i /etc/resolv.conf
When working with systemd-resolved, you'll notice that /etc/resolv.conf
is just a symlink to /run/systemd/resolve/stub-resolv.conf
and contains a warning that it shouldn't be edited directly. The file typically looks like this:
# This file is managed by man:systemd-resolved(8). Do not edit.
nameserver 127.0.0.53
options edns0
Any manual changes you make here will be overwritten on reboot because systemd-resolved manages this file dynamically.
To permanently add your custom DNS server (192.168.X.Y) and search domain (foo.local), you have several options:
Method 1: Using systemd-resolved Configuration Files
Edit or create the following file:
sudo nano /etc/systemd/resolved.conf
Add these lines under the [Resolve] section:
[Resolve]
DNS=192.168.X.Y
Domains=foo.local
Then restart the service:
sudo systemctl restart systemd-resolved
Method 2: Using Netplan (Ubuntu 18.04+)
Edit your netplan configuration:
sudo nano /etc/netplan/01-netcfg.yaml
Add DNS configuration under your network interface:
network:
version: 2
ethernets:
ens2:
dhcp4: yes
nameservers:
addresses: [192.168.X.Y, 8.8.8.8]
search: [foo.local]
Apply the changes:
sudo netplan apply
Method 3: Using resolvectl (Alternative Command)
You can also use the resolvectl command:
sudo resolvectl dns ens2 192.168.X.Y
sudo resolvectl domain ens2 "foo.local"
Check if your settings are applied correctly:
systemd-resolve --status
You should see your custom DNS server and search domain listed in the output for the appropriate network interface.
- If changes don't take effect, try:
sudo systemctl daemon-reload && sudo systemctl restart systemd-resolved
- Check for syntax errors in your configuration files
- Verify your network interface name with
ip a
and use the correct one in configurations
systemd-resolved works by:
- Receiving DNS queries from applications
- Forwarding them to configured upstream DNS servers
- Caching responses
- Managing the
/etc/resolv.conf
symlink dynamically
This is why direct edits to resolv.conf don't persist - the file is regenerated based on systemd-resolved's internal configuration.