How to Permanently Add a Custom DNS Server in Ubuntu 18.04 Using systemd-resolved


7 views

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:

  1. Receiving DNS queries from applications
  2. Forwarding them to configured upstream DNS servers
  3. Caching responses
  4. 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.