Skip to content

How do I assign a static DNS server to an EC2 instance that persists when I reboot?

8 minute read
1

I want to configure an Amazon Elastic Compute Cloud (Amazon EC2) instance with a static DNS server that persists when I reboot.

Resolution

By default, EC2 instances that you associate with Amazon Virtual Private Cloud (Amazon VPC) request a DNS server address at startup. The Dynamic Host Configuration Protocol (DHCP) sends the request, and then Amazon writes the DHCP response with the DNS server addresses to the local /etc/resolv.conf file.

When you restart the instance, you lose manual modifications to the resolv.conf file that contains custom DNS server addresses. To maintain your static DNS server when you reboot your instance, update your configuration based on your Linux distribution.

Important: Before you change your instance, use an Amazon Machine Image (AMI) to create a backup. Or, use an Amazon Elastic Block Store (Amazon EBS) snapshot to create a backup. When you change the networking configurations for an instance, the instance might become unreachable.

AL2023

Amazon Linux 2023 (AL2023) uses systemd-resolved. For more information, see systemd-resolved on the Archlinux website.

Configure the resolver

Edit the /etc/systemd/resolved.conf file and change the DNS and domain options.

Example configuration file:

# /etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8
Domains=~.

Or, create a drop-in. For example, use the /etc/systemd/resolved.conf.d/dns_servers.conf file.

Example configuration file:

#/etc/systemd/resolved.conf.d/dns_servers.conf
[Resolve]
DNS=8.8.8.8 8.8.4.4
Domains=~.

Note: Set the Domains=~. option so that systemd-resolved doesn't use the per-link DNS servers set in the per-link configuration. The Domains=~. option doesn't affect queries of domain names that match specific search domains that you specify in per-link configurations. When domain names resolve, they use their per-link DNS servers.

Change the location that /etc/resolv.conf points

By default, /etc/resolv.conf points to the local host stub resolver. To change the resolver, recreate the file with updated fields, or point somewhere other than the local host stub resolver. For example, point to the /run/systemd/resolve/resolv.conf file that contains a flattened list of servers that systemd-resolved uses.

To check the symbolic link status, run the following command:

ls -al /etc/resolv.conf

Example configuration file status when you use the local DNS cache:

### Symbolic link status : point to stub-resolv.conf
### Flow: DNS query => Local Cache DNS 127.0.0.53 ( systemd-resolved ) => External DNS 

# ls -al /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Mar  5 02:28 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

# cat /etc/resolv.conf
nameserver 127.0.0.53      
options edns0 trust-ad
search .

### 127.0.0.53 is used for systemd-resolved ( local cache dns )
# lsof -nP -p `pidof systemd-resolved` |grep TCP
systemd-r 339 systemd-resolve   14u     IPv4               2753      0t0  TCP 127.0.0.53:53 (LISTEN)

Example configuration file status when you don't use the local DNS cache:

### Symbolic link status : point to /run/systemd/resolve/resolv.conf

# cat  /run/systemd/resolve/resolv.conf
nameserver 1.1.1.1
nameserver 1.0.0.1
search .

If the link points to stub-resolv.conf, then run the following command to point to the ../run/systemd/resolve/resolv.conf file and not use the local DNS cache:

ln -sf ../run/systemd/resolve/resolv.conf /etc/resolv.conf

To check the link status, re-run the following command:

ls -al /etc/resolv.conf

Example output:

ls -al /etc/resolv.conf
lrwxrwxrwx 1 root root 34 Apr  1 16:05 /etc/resolv.conf -> ../run/systemd/resolve/resolv.conf

To test your configuration, run the following commands:

# resolvectl status
# resolvectl query amazonaws.com

Example outputs:

# resolvectl status

Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: uplink
      DNS Servers 8.8.8.8 8.8.4.4
       DNS Domain ~.

Link 2 (ens5)
Current Scopes: DNS
     Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
   DNS Servers: 10.2.0.2
    DNS Domain: ap-northeast-2.compute.internal
# resolvectl query amazonaws.com
amazonaws.com: 207.171.166.22                               -- link: ens5
               72.21.206.80                                 -- link: ens5
               72.21.210.29                                 -- link: ens5

-- Information acquired via protocol DNS in 3.0ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: cache

AL1 or AL2

To configure your Amazon Linux 1 (AL1) or Amazon Linux 2 (AL2) instances, update the etc/dhcp/dhclient.conf file or the ifcfg-eth0.conf file. If you configure both files, then the DNS servers that you specify in the ifcfg-eth0.conf file take precedence.

Prerequisites: Set the PEERDNS parameter value in the ifcfg-eth0.conf file to yes. When you set the PEERDNS parameter to no, Amazon EC2 ignores the DNS servers specified in ifcfg-* files or that DHCP provides.

Update the /etc/dhcp/dhclient.conf file

Complete the following steps:

  1. Open the existing /etc/dhcp/dhclient.conf file. Or, create a new one.
    Note: You must have root user permissions to edit this file. Either use sudo -i to become the root user, or use sudo to implement all commands.
  2. To override the domain-name-servers, add the following supersede command to the file:
    supersede domain-name-servers 000.000.000.000, 000.000.000.000;
    Note: Replace 000.000.000.000 with the IP address of the DNS server or servers that you want the instance to use.
  3. Set the PEERDNS parameter to yes in your per-interface configuration file, such as /etc/sysconfig/network-scripts/ifcfg-*.
  4. Reboot the EC2 instance. The resolv.conf file updates at instance reboot to contain only the DNS servers that you specified in the dhclient file.

Update the ifcfj-eth0 file

Complete the following steps:

  1. To override DNS server values in the /etc/dhcp/dhclient.conf file, specify the custom DNS servers in the per-interface configuration files.
    The following example file shows the /etc/sysconfig/network-scripts/ifcfg-eth0 file from an Amazon Linux instance that includes two custom DNS servers:

    DEVICE=eth0
    BOOTPROTO=dhcp
    ONBOOT=yes
    TYPE=Ethernet
    USERCTL=yes
    PEERDNS=yes
    IPV6INIT=no
    PERSISTENT_DHCLIENT=yes
    RES_OPTIONS="timeout:2 attempts:5"
    DHCP_ARP_CHECK=no
    MTU="9001"
    DNS1=8.8.8.8
    DNS2=8.8.4.4
  2. Set the PEERDNS parameter to yes in your per-interface configuration file, such as /etc/sysconfig/network-scripts/ifcfg-*.

Note: If your instance runs Ubuntu 16.04 or Red Hat Enterprise Linux (RHEL) 7.5, then you can also use the preceding resolution steps.

Ubuntu 18.04, 20.04, and 22.04

On Ubuntu 18.04, the netplan.io package manages the network interface configuration, and the systemd-resolved service uses a stub resolver to manage DNS queries. The stub resolver IP address is located in the /etc/resolv.conf file that's a symlink to the /run/systemd/resolve/stub-resolv.conf file. If the /etc/resolv.conf file has the following configurations, then the supersede statement in /etc/dhcp/dhclient.conf might not work as expected:

  • The file isn't a symlink on your instance.
  • The file is a symlink that points to a different file, such as /run/systemd/resolve/resolv.conf.

To override the DNS server values, complete the following steps:

  1. Create a file that's named /etc/netplan/99-custom-dns.yaml with the following data:

    ### Create Customer DNS config
    # cat << 'EOF' | sudo tee /etc/netplan/99-custom-dns.yaml
    network:
      version: 2
      ethernets:
        ens5:
          nameservers:
            addresses: [1.1.1.1, 1.0.0.1]
          dhcp4-overrides:
            use-dns: false
            use-domains: false
    EOF
    
    ### Required File Permission
    # chmod 600 /etc/netplan/99-custom-dns.yaml
    
    ### Checking Netplan Configuration status
    # netplan get
    network:
      version: 2
      ethernets:
        ens5:
          match:
            macaddress: "0a:e5:a1:40:a2:f5"
          nameservers:
            addresses:
            - 1.1.1.1
            - 1.0.0.1
          dhcp4: true
          dhcp4-overrides:
            use-dns: false
            use-domains: false
          dhcp6: false
          set-name: "ens5"

    Note: Replace 1.1.1.1, 1.0.0.1 with your DNS server IP address. Netplan stores configuration files in the /etc/netplan directory. The preceding example uses the ens5 interface. Make sure that the interface name matches your interface. To see your interface name, run the following command:

    # ip a

    Example output:

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
        link/ether 0a:e5:a1:40:a2:f5 brd ff:ff:ff:ff:ff:ff
        inet 172.31.35.233/20 metric 100 brd 172.31.47.255 scope global dynamic ens5
           valid_lft 2828sec preferred_lft 2828sec
        inet6 fe80::8e5:a1ff:fe40:a2f5/64 scope link
           valid_lft forever preferred_lft forever
  2. To convert the Netplan YAML file into configuration files, run the following netplan commands:

    # netplan generate
    # netplan try
    # netplan apply

    Note: You might receive the "WARNING:root:Cannot call Open vSwitch: ovsdb-server.service is not running" message. You can ignore this message and proceed to the next step. If you don't want to see the WARNING message, then install the Open vSwitch with DPDK package. The stub resolver IP address is now in /etc/resolv.conf. This is an expected behavior because the stub resolver IP address is local to your operating system (OS). In the background, the stub resolver uses the DNS servers that you specified in the 99-custom-dns.yaml file.

  3. Reboot the instance.

  4. To confirm that the system correctly uses the intended DNS server IP addresses, run the following command based on your Ubuntu version:
    Ubuntu 18.04:

    systemd-resolve --status

    Ubuntu 20.04 and 22.04:

    resolvectl status

RHEL 7.5

By default, the NetworkManager service manages the resolv.conf file for RHEL distributions. The service then populates the file with DNS servers that DHCP provides. To use custom DNS servers, block NetworkManager in the resolv.conf file so that the resolv.conf file ignores the DNS servers that DHCP provides.

Complete the steps for Update the /etc/dhcp/dhclient.conf file under AL1 or AL2. Or, create the /etc/NetworkManager/conf.d/90-dns-none.conf file with the following content:

[main]
dns=none

Reboot the instance, and then manually create the /etc/resolv.conf file.

Related information

DHCP option sets in Amazon VPC

network files on the Archlinux website

resolved.conf(5) on the Archlinux website

dhclient.conf(5) on the Archlinux website

networkmanager.conf(5) on the Archlinux website

AWS OFFICIALUpdated 6 months ago
1 Comment

I saw that the instructions only go up to Ubuntu 18.04, so I went through the same process on a standard Ubuntu 22.04 instance, to check if it's the same as the 18.04 instructions in this article. It's not.

Here are the differences in Ubuntu 22.04:

STEP 1) In step #1, don't include the first and last (EOF) lines. The rest of that step is ok. Example:

network:
  version: 2
  ethernets:
    ens5:
      nameservers:
        addresses: [1.1.1.1, 1.0.0.1]
      dhcp4-overrides:
        use-dns: false
        use-domains: false

STEP 2) In step #2, also run a second 'netplan' command to actually apply the new configuration:

netplan generate
netplan apply

You may need to install 'openswitch', if you receive an error message stating that it's missing:

apt install openvswitch-switch-dpdk

STEP 3) Reboot step is good as-is.

STEP 4) In step #4, the 'systemd-resolve' command doesn't work. Use the following command instead, to check if your custom DNS server IP addresses were retained through reboot:

resolvectl status
AWS
replied a year ago