[Amazon Linux 2023版] DHCP option setsで設定したDNSサーバー以外のDNSサーバーを指定する方法

Amazon Linux 2と設定方法が異なるので注意しよう
2023.04.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

このEC2インスタンスだけ異なるDNSサーバーを使って問い合わせをさせたい

こんにちは、のんピ(@non____97)です。

皆さんはDHCP option setsで設定したDNSサーバー以外のDNSサーバーを指定したいなと思ったことはありますか? 私はあります。

以下記事で紹介している通り、デフォルトだと/etc/resolv.confを変更してもnetworkサービスを再起動すると、DHCP option setsで指定したDNSサーバーに戻ってしまいます。

Amazon Linux 2の場合、networkサービス再起動後も/etc/resolv.confの設定を維持するためには/etc/dhcp/dhclient.confもしくは/etc/sysconfig/network-scripts/ifcfg-eth0の変更が必要でした。

Amazon Linux 2023では新しくsystemd-resolved.serviceが起動しています。

systemd-resolvedの詳細は以下ドキュメントをご覧ください。

これにより、DNSサーバーを指定する方法が変わりました。

re:PostにもAmazon Linux 2023版の設定方法が紹介されています。

実際に試してみたので紹介します。

いきなりまとめ

  • Amazon Linux 2023ではDNSの設定を固定するには/etc/systemd/resolved.confを変更する
    • systemd-resolved.serviceが動作しているため
    • ただし、デフォルトでは名前解決をする際はsystemd-resolved.serviceは使用していない
  • /etc/systemd/resolved.confを変更しても、DHCP option setsで設定したDNSサーバーの設定は残る

/etc/resolv.confを手動で変更してみる

デフォルトの/etc/resolv.confの確認

まず、/etc/resolv.confを手動で変更してみて、OS再起動後リセットされているかを確認します。

現在の/etc/resolv.confを確認します。

$ cat /etc/resolv.conf
# This is /run/systemd/resolve/resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
#
# This file might be symlinked as /etc/resolv.conf. If you're looking at
# /etc/resolv.conf and seeing this text, you have followed the symlink.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 172.31.0.2
search ec2.internal

デフォルトで参照しているDNSサーバーは172.31.0.2(Route 53 Resolver)で、searchはec2.internalでした。

ただし、コメントに「これはsystemd-resolvedで管理されている/run/systemd/resolve/resolv.confだ。編集するな。/etc/resolv.confのシンボリックリンクかも知れないぞ。」と記載されていました。

ls -lをしてみると確かに/etc/resolv.conf/run/systemd/resolve/resolv.confのシンボリックリンクであることが分かります。

$ ls -l /etc/resolv.conf
lrwxrwxrwx. 1 root root 32 Mar 13 23:37 /etc/resolv.conf -> /run/systemd/resolve/resolv.conf

また、172.31.0.2を参照しているので当然ですが、Local DNS Stub Listenerは使用しないようになっていました。

$ ls -l /usr/lib/systemd/resolved.conf.d/
total 4
-rw-r--r--. 1 root root 231 Mar 10 00:44 resolved-disable-stub-listener.conf

$ cat /usr/lib/systemd/resolved.conf.d/resolved-disable-stub-listener.conf
# Amazon Linux systems do not use the stub listener by default, so we
# disable it in order to reduce the runtime footprint and to avoid
# triggering https://bugzilla.redhat.com/show_bug.cgi?id=2115094
[Resolve]
DNSStubListener=no

試しに名前解決してみましょう。

$ dig ip-10-0-1-10.ec2.internal +noall +answer +stats
ip-10-0-1-10.ec2.internal. 60	IN	A	10.0.1.10
;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Apr 18 10:57:19 UTC 2023
;; MSG SIZE  rcvd: 70

# searchにより補完されるか確認
$ dig ip-10-0-1-10 +noall +answer +stats +search
ip-10-0-1-10.ec2.internal. 60	IN	A	10.0.1.10
;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Apr 18 10:58:51 UTC 2023
;; MSG SIZE  rcvd: 70

# のんピ所有のドメインに登録したDNSレコード dns-test.non-97.net の名前解決 
$ dig dns-test.non-97.net +noall +answer +stats
dns-test.non-97.net.	300	IN	A	172.31.10.89
;; Query time: 39 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Apr 18 10:59:40 UTC 2023
;; MSG SIZE  rcvd: 64

名前解決できましたね。searchもしっかり効いています。

systemd-resolvedがインストールされているためresolvectlを使用することも可能です。

# 現在のグローバルおよびリンクごとのDNS設定の確認
$ resolvectl
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: uplink

Link 2 (ens5)
Current Scopes: DNS
     Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
   DNS Servers: 172.31.0.2
    DNS Domain: ec2.internal

# 現在のグローバルおよびリンクごとに参照しているDNSサーバーの確認
$ resolvectl dns
Global:
Link 2 (ens5): 172.31.0.2

# 現在のグローバルおよびリンクごとに設定されている search の確認
$ resolvectl domain
Global:
Link 2 (ens5): ec2.internal

Link 2 (ens5)+DefaultRouteが付与されているので、グローバルがない現在は1.1.1.1を使って問い合わせることが分かります。

resolvectlを使った名前解決も試してみましょう。

$ resolvectl query ip-10-0-1-10.ec2.internal
ip-10-0-1-10.ec2.internal: 10.0.1.10                        -- link: ens5

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

# キャッシュの削除
$ resolvectl flush-caches

$ resolvectl query ip-10-0-1-10
ip-10-0-1-10: 10.0.1.10                                     -- link: ens5
              (ip-10-0-1-10.ec2.internal)

-- Information acquired via protocol DNS in 861us.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network

$ resolvectl query dns-test.non-97.net
dns-test.non-97.net: 172.31.10.89                           -- link: ens5

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

いずれも名前解決できましたね。

systemd-resolvedにおける名前解決の順序はman:systemd-resolved(8)のPROTOCOLS AND ROUTINGに記載されています。

ただし、/etc/nsswitch.confを確認すると、hostsの行にresolveがありませんでした。そのため、名前解決の際にはsystemd-resolvedの設定は参照しなさそうなので注意が必要です。

$ cat /etc/nsswitch.conf
#
# /etc/nsswitch.conf
#
# Name Service Switch config file. This file should be
# sorted with the most-used services at the beginning.
#
# Valid databases are: aliases, ethers, group, gshadow, hosts,
# initgroups, netgroup, networks, passwd, protocols, publickey,
# rpc, services, and shadow.
#
# Valid service provider entries include (in alphabetical order):
#
#	compat			Use /etc files plus *_compat pseudo-db
#	db			Use the pre-processed /var/db files
#	dns			Use DNS (Domain Name Service)
#	files			Use the local files in /etc
#	hesiod			Use Hesiod (DNS) for user lookups
#
# See `info libc 'NSS Basics'` for more information.
#
# Commonly used alternative service providers (may need installation):
#
#	ldap			Use LDAP directory server
#	myhostname		Use systemd host names
#	mymachines		Use systemd machine names
#	mdns*, mdns*_minimal	Use Avahi mDNS/DNS-SD
#	resolve			Use systemd resolved resolver
#	sss			Use System Security Services Daemon (sssd)
#	systemd			Use systemd for dynamic user option
#	winbind			Use Samba winbind support
#	wins			Use Samba wins support
#	wrapper			Use wrapper module for testing
#
# Notes:
#
# 'sssd' performs its own 'files'-based caching, so it should generally
# come before 'files'.
#
# WARNING: Running nscd with a secondary caching service like sssd may
# 	   lead to unexpected behaviour, especially with how long
# 	   entries are cached.
#
# Installation instructions:
#
# To use 'db', install the appropriate package(s) (provide 'makedb' and
# libnss_db.so.*), and place the 'db' in front of 'files' for entries
# you want to be looked up first in the databases, like this:
#
# passwd:    db files
# shadow:    db files
# group:     db files

# In order of likelihood of use to accelerate lookup.
passwd:     sss files
shadow:     files
group:      sss files
hosts:      files dns myhostname
services:   files sss
netgroup:   sss
automount:  files sss

aliases:    files
ethers:     files
gshadow:    files
# Allow initgroups to default to the setting for group.
# initgroups: files
networks:   files dns
protocols:  files
publickey:  files
rpc:        files

/etc/resolv.confの変更

それでは/etc/resolv.confを変更してみます。

今回はDNSサーバーを1.1.1.1、searchをnon-97.netとします。

$ sudo vi /etc/resolv.conf

# 設定内容の確認
$ tail -n2 /etc/resolv.conf
nameserver 1.1.1.1
search non-97.net

設定変更後名前解決してみます。

# ec2.internalのホストの名前解決
$ dig ip-10-0-1-10.ec2.internal +noall +answer +stats
;; Query time: 0 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Apr 18 11:03:52 UTC 2023
;; MSG SIZE  rcvd: 129

# のんピ所有のドメインに登録したDNSレコード dns-test.non-97.net の名前解決 
$ dig dns-test.non-97.net +noall +answer +stats
dns-test.non-97.net.	3600	IN	A	172.31.10.89
;; Query time: 70 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Apr 18 11:04:36 UTC 2023
;; MSG SIZE  rcvd: 64

# searchにより補完されるか確認
$ dig dns-test.non-97.net +noall +answer +stats +search
dns-test.non-97.net.	3600	IN	A	172.31.10.89
;; Query time: 30 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Apr 18 11:04:55 UTC 2023
;; MSG SIZE  rcvd: 64

DNSの名前解決の問い合わせ先が1.1.1.1になりましたね。これにより、ec2.internalのホストの名前解決ができなくなりました。

また、searchでnon-97.netについて補完されるようになりました。

resolvectlも確認してみます。

# 現在のグローバルおよびリンクごとのDNS設定の確認
$ resolvectl
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: uplink

Link 2 (ens5)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 172.31.0.2
       DNS Servers: 172.31.0.2
        DNS Domain: ec2.internal

# 現在のグローバルおよびリンクごとに参照しているDNSサーバーの確認
$ resolvectl dns
Global:
Link 2 (ens5): 172.31.0.2

# 現在のグローバルおよびリンクごとに設定されている search の確認
$ resolvectl domain
Global:
Link 2 (ens5): ec2.internal

# 名前解決
# ec2.internalのホスト
$ resolvectl query ip-10-0-1-10.ec2.internal
ip-10-0-1-10.ec2.internal: 10.0.1.10                        -- link: ens5

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

# キャッシュ削除
$ resolvectl flush-caches

# ec2.internalのホストのsearch確認
$ resolvectl query ip-10-0-1-10
ip-10-0-1-10: 10.0.1.10                                     -- link: ens5
              (ip-10-0-1-10.ec2.internal)

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

# のんピ所有のドメインに登録したDNSレコード
$ resolvectl query dns-test.non-97.net
dns-test.non-97.net: 172.31.10.89                           -- link: ens5

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

# キャッシュ削除
$ resolvectl flush-caches

# のんピ所有のドメインに登録したDNSレコードについてのsearch確認
$ resolvectl query dns-test
dns-test: resolve call failed: 'dns-test' not found

こちらはec2.internalのホストの名前解決ができました。resolvectlによる名前解決は/etc/nsswitch.confに従って/etc/resolv.confを参照するといったことはしないかもしれませんね。

第3の手法としてping実行時の名前解決を確認します。

$ ping dns-test -c 1 | head -n1
PING dns-test.non-97.net (172.31.10.89) 56(84) bytes of data.

$ ping ip-10-0-1-10 -c 1 | head -n1
ping: ip-10-0-1-10: Name or service not known

$ ping ip-10-0-1-10.ec2.internal -c 1 | head -n1
ping: ip-10-0-1-10.ec2.internal: Name or service not known

searchが効いていないことから、/etc/resolv.confの設定を参照した上で名前解決していそうです。

systemd-networkd の再起動

それではsystemd-networkd.serviceを再起動します。

$ sudo systemctl restart systemd-networkd

/etc/resolv.confが元に戻ったのか確認します。

$ tail -n2 /etc/resolv.conf
nameserver 172.31.0.2
search ec2.internal

元の値に戻りましたね。

各種名前解決をします。

$ dig ip-10-0-1-10.ec2.internal +noall +answer +stats
ip-10-0-1-10.ec2.internal. 60	IN	A	10.0.1.10
;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Apr 18 11:11:05 UTC 2023
;; MSG SIZE  rcvd: 70

$ dig ip-10-0-1-10 +noall +answer +stats +search
ip-10-0-1-10.ec2.internal. 43	IN	A	10.0.1.10
;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Apr 18 11:11:22 UTC 2023
;; MSG SIZE  rcvd: 70

$ dig dns-test.non-97.net +noall +answer +stats
dns-test.non-97.net.	300	IN	A	172.31.10.89
;; Query time: 60 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Apr 18 11:11:33 UTC 2023
;; MSG SIZE  rcvd: 64

$ dig dns-test +noall +answer +stats +search
;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Apr 18 11:11:41 UTC 2023
;; MSG SIZE  rcvd: 112

設定変更前と同じく172.31.0.2に問い合わせを行っています。ec2.internalのホストの名前解決もできています。

resolvectlも確認します。

# 現在のグローバルおよびリンクごとのDNS設定の確認
$ resolvectl
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: uplink

Link 2 (ens5)
Current Scopes: DNS
     Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
   DNS Servers: 172.31.0.2
    DNS Domain: ec2.internal

# 現在のグローバルおよびリンクごとに参照しているDNSサーバーの確認
$ resolvectl dns
Global:
Link 2 (ens5): 172.31.0.2

# 現在のグローバルおよびリンクごとに設定されている search の確認
$ resolvectl domain
Global:
Link 2 (ens5): ec2.internal

# 名前解決
# ec2.internalのホスト
$ resolvectl query ip-172-31-10-89.ec2.internal
ip-172-31-10-89.ec2.internal: 172.31.10.89                  -- link: ens5

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

# キャッシュ削除
$ resolvectl flush-caches

# ec2.internalのホストのsearch確認
$ resolvectl query ip-172-31-10-89
ip-172-31-10-89: 172.31.10.89                               -- link: ens5
                 (ip-172-31-10-89.ec2.internal)

-- Information acquired via protocol DNS in 865us.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network

# のんピ所有のドメインに登録したDNSレコード
$ resolvectl query dns-test.non-97.net
dns-test.non-97.net: 172.31.10.89                           -- link: ens5

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

# キャッシュ削除
$ resolvectl flush-caches

# のんピ所有のドメインに登録したDNSレコードについてのsearch確認
$ resolvectl query dns-test
dns-test: resolve call failed: 'dns-test' not found

こちらは特に変わらずといったところです。

/etc/systemd/resolved.conf によるDNSの設定

/etc/systemd/resolved.conf の設定変更

re:Postの情報を確認すると、DNSの設定を固定するには/etc/systemd/resolved.confを変更すると記載がありました。

AWS公式ドキュメントを確認すると/etc/systemd/resolved.conf/run/systemd/networkで設定されたデフォルト値を上書きすることができると記載がありました。

The amazon-ec2-net-utils package generates interface-specific configurations in the /run/systemd/network directory. These configurations enable both IPv4 and IPv6 networking on interfaces when they're attached to an instance. These configurations also install policy routing rules that help ensure that locally sourced traffic is routed to the network through the corresponding instance's network interface. These rules do this by ensuring that the right traffic is routed through the Elastic Network Interface (ENI) from the associated addresses or prefixes. For more information about using ENI, see Using ENI in the Amazon EC2 User Guide for Linux Instances.

You can customize this networking behavior by placing a custom configuration file in the /etc/systemd/network directory to override the default configuration settings contained in /run/systemd/network.

(以下機械翻訳)

amazon-ec2-net-utils パッケージは /run/systemd/network ディレクトリにインターフェース固有の設定を生成します。これらの設定は、インスタンスに接続されたインターフェイスでIPv4とIPv6の両方のネットワーキングを有効にします。また、これらの構成は、ローカルに発生したトラフィックが対応するインスタンスのネットワークインターフェイスを通じてネットワークにルーティングされることを保証するのに役立つポリシールーティングルールをインストールします。これらのルールは、関連するアドレスまたはプレフィックスからElastic Network Interface (ENI)を介して正しいトラフィックがルーティングされることを保証することでこれを実現します。ENIの使用に関する詳細については、『Amazon EC2 User Guide for Linux Instances』の「ENIの使用」を参照してください。

このネットワーク動作は、/etc/systemd/networkディレクトリにカスタム構成ファイルを配置して、/run/systemd/networkに含まれるデフォルト構成設定をオーバーライドすることでカスタマイズできます。

Networking service - Amazon Linux 2023

/run/systemd/network配下のファイルを確認してみます。

$ ls -l /run/systemd/network
total 0
lrwxrwxrwx. 1 root root 39 Apr 14 04:32 70-ens5.network -> /usr/lib/systemd/network/80-ec2.network
drwxr-xr-x. 2 root root 60 Apr 14 05:14 70-ens5.network.d

$ cat /usr/lib/systemd/network/80-ec2.network
[Match]
Driver=ena ixgbevf vif

[Link]
MTUBytes=9001

[Network]
DHCP=yes
IPv6DuplicateAddressDetection=0
LLMNR=no
DNSDefaultRoute=yes

[DHCPv4]
UseHostname=no
UseDNS=yes
UseNTP=yes
UseDomains=yes

[DHCPv6]
UseHostname=no
UseDNS=yes
UseNTP=yes
WithoutRA=solicit

[Route]
Gateway=_ipv6ra

[IPv6AcceptRA]
UseDomains=yes

ls -l /run/systemd/network/70-ens5.network.d/
total 4
-rw-r--r--. 1 root root 171 Apr 14 04:32 eni.conf

$ cat /run/systemd/network/70-ens5.network.d/eni.conf
# Configuration for ens5 generated by policy-routes@ens5.service
[Match]
MACAddress=02:2c:62:cf:f9:37
[Network]
DHCP=yes
[DHCPv4]
RouteMetric=512
[DHCPv6]
RouteMetric=512

UseDNS=yesUseDomains=yesでDHCP option setsの設定値をDNSに反映していそうですね。

それでは、/etc/systemd/resolved.confを変更します。

設定変更前に現在の設定を確認します。

$ ls -l /etc/systemd/resolved.conf
-rw-r--r--. 1 root root 1415 Apr 14 09:04 /etc/systemd/resolved.conf

$ cat /etc/systemd/resolved.conf
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it under the
#  terms of the GNU Lesser General Public License as published by the Free
#  Software Foundation; either version 2.1 of the License, or (at your option)
#  any later version.
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file, or by creating "drop-ins" in
# the resolved.conf.d/ subdirectory. The latter is generally recommended.
# Defaults can be restored by simply deleting this file and all drop-ins.
#
# Use 'systemd-analyze cat-config systemd/resolved.conf' to display the full config.
#
# See resolved.conf(5) for details.

[Resolve]
# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
# Cloudflare: 1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com
# Google:     8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
# Quad9:      9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
#DNS=
#FallbackDNS=
#Domains=
#DNSSEC=no
#DNSOverTLS=no
#MulticastDNS=no
#LLMNR=no
#Cache=yes
#CacheFromLocalhost=no
#DNSStubListener=yes
#DNSStubListenerExtra=
#ReadEtcHosts=yes
#ResolveUnicastSingleLabel=no

全てコメントアウトされているのでデフォルト値をオーバーライドしているものはないようですね。各パラメーターの詳細は以下ドキュメントをご覧ください。

DNSサーバーは1.1.1.1を参照するにようにし、searchはnon-97.netとなるように設定します。

# 設定変更
$ sudo vi /etc/systemd/resolved.conf

# 設定変更内容の確認
$ tail -n15 /etc/systemd/resolved.conf
# Google:     8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
# Quad9:      9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
DNS=1.1.1.1
#FallbackDNS=
Domains=non-97.net
#DNSSEC=no
#DNSOverTLS=no
#MulticastDNS=no
#LLMNR=no
#Cache=yes
#CacheFromLocalhost=no
#DNSStubListener=yes
#DNSStubListenerExtra=
#ReadEtcHosts=yes
#ResolveUnicastSingleLabel=no

# 設定の反映
$ sudo systemctl restart systemd-resolved.service

設定変更後/etc/resolv.confを確認します。

$ tail /etc/resolv.conf
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 1.1.1.1
nameserver 172.31.0.2
search non-97.net ec2.internal

nameserversearchにそれぞれ設定した値が追加されましたね。

実際に名前解決してみます。

$ dig ip-10-0-1-10.ec2.internal +noall +answer +stats
;; Query time: 0 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Apr 18 11:14:30 UTC 2023
;; MSG SIZE  rcvd: 129

$ dig ip-10-0-1-10 +noall +answer +stats +search
;; Query time: 0 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Apr 18 11:14:37 UTC 2023
;; MSG SIZE  rcvd: 116

$ dig dns-test.non-97.net +noall +answer +stats
dns-test.non-97.net.	3600	IN	A	172.31.10.89
;; Query time: 60 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Apr 18 11:14:43 UTC 2023
;; MSG SIZE  rcvd: 64

$ dig dns-test +noall +answer +stats +search
dns-test.non-97.net.	3600	IN	A	172.31.10.89
;; Query time: 60 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Tue Apr 18 11:14:53 UTC 2023
;; MSG SIZE  rcvd: 64

いずれのパターンも1.1.1.1を参照していますね。そのためec2.internalのホストの名前解決に失敗しています。また、searchによりnon-97.netの補完も効いています。

resolvectlも確認します。

# 現在のグローバルおよびリンクごとのDNS設定の確認
$ resolvectl
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: uplink
     DNS Servers: 1.1.1.1
      DNS Domain: non-97.net

Link 2 (ens5)
Current Scopes: DNS
     Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
   DNS Servers: 172.31.0.2
    DNS Domain: ec2.internal

# 現在のグローバルおよびリンクごとに参照しているDNSサーバーの確認
$ resolvectl dns
Global: 1.1.1.1
Link 2 (ens5): 172.31.0.2

# 現在のグローバルおよびリンクごとに設定されている search の確認
$ resolvectl domain
Global: non-97.net
Link 2 (ens5): ec2.internal

# 名前解決
# ec2.internalのホスト
$ resolvectl query ip-10-0-1-10.ec2.internal
ip-10-0-1-10.ec2.internal: 10.0.1.10                        -- link: ens5

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

# キャッシュ削除
$ resolvectl flush-caches

# ec2.internalのホストのsearch確認
$ resolvectl query ip-10-0-1-10
ip-10-0-1-10: 10.0.1.10                                     -- link: ens5
              (ip-10-0-1-10.ec2.internal)

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

# のんピ所有のドメインに登録したDNSレコード
$ resolvectl query dns-test.non-97.net
dns-test.non-97.net: 172.31.10.89                           -- link: ens5

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

# キャッシュ削除
$ resolvectl flush-caches

# のんピ所有のドメインに登録したDNSレコードについてのsearch確認
$ resolvectl query dns-test
dns-test: 172.31.10.89                                      -- link: ens5
          (dns-test.non-97.net)

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

こちらはec2.internalのホストip-172-31-10-89.ec2.internalの名前解決もできました。systemd-resolvedにより、ec2.internalとマッチするリンクens5にルーティングされて名前解決していることが分かりました。

pingでも試してみます。

# のんピ所有のドメインに登録したDNSレコードについてのsearch確認
$ ping dns-test -c 1 | head -n1
PING dns-test.non-97.net (172.31.10.89) 56(84) bytes of data.

# ec2.internalのホストのsearch確認
$ ping ip-10-0-1-10 -c 1 | head -n1
ping: ip-10-0-1-10: Name or service not known

# ec2.internalのホスト
$ ping ip-10-0-1-10.ec2.internal -c 1 | head -n1
ping: ip-10-0-1-10.ec2.internal: Name or service not known

# 自ホスト
$ ping ip-172-31-10-89.ec2.internal -c 1 | head -n1
PING ip-172-31-10-89.ec2.internal(ip-172-31-10-89.ec2.internal (fe80::2c:62ff:fecf:f937%ens5)) 56 data bytes

やはり、ec2.internalのホストのsearchは失敗しました。

なお、自ホストについての名前解決は成功しました。

systemd-networkd の再起動

systemd-networkdの再起動を行い、/etc/resolv.confがリセットされていないことを確認します。

# systemd-networkd の再起動
$ sudo systemctl restart systemd-networkd

# /etc/resolv.conf の確認
$ tail /etc/resolv.conf
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 1.1.1.1
nameserver 172.31.0.2
search non-97.net ec2.internal

# 現在のグローバルおよびリンクごとのDNS設定の確認
$ resolvectl status
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: uplink
Current DNS Server: 1.1.1.1
       DNS Servers: 1.1.1.1
        DNS Domain: non-97.net

Link 2 (ens5)
Current Scopes: DNS
     Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
   DNS Servers: 172.31.0.2
    DNS Domain: ec2.internal

systemd-networkdを再起動しても/etc/resolv.confはリセットされていませんね。

ということで、DNSの設定を固定するには/etc/systemd/resolved.confを変更しましょう。

systemd-resolved を使って名前解決するように変更

せっかくなので/etc/nsswitch.confを変更して、systemd-resolvedを使って名前解決するようにしてみます。

nss-resolve(8)を参考に/etc/nsswitch.confを変更して、resolve [!UNAVAIL=return]を dnsよりも優先的に使用するようにします。

# /etc/nsswitch.conf の編集
$ sudo vi /etc/nsswitch.conf

# 編集箇所の確認
$ grep hosts: /etc/nsswitch.conf
hosts:      files resolve [!UNAVAIL=return] dns myhostname

変更後、ec2.internalのホストのsearchが上手く動作するのか確認します。

# ec2.internalのホストのsearch確認
$ ping ip-10-0-1-10 -c 1 | head -n1
PING ip-10-0-1-10.ec2.internal (10.0.1.10) 56(84) bytes of data.

# ec2.internalのホストの名前解決
$ ping ip-10-0-1-10.ec2.internal -c 1 | head -n1
PING ip-10-0-1-10.ec2.internal (10.0.1.10) 56(84) bytes of data.

名前解決できましたね。

その時のWiresharkの結果は以下のとおりです。

  • ec2.internalのホストのsearch確認

systemd-resolved_running_search

  • ec2.internalのホストの名前解決

systemd-resolved_running_nosearch

「ec2.internalのホストのsearch確認」の場合は、まずnon-97.netをサフィックスに付与してグローバルのDNS1.1.1.1へ問い合わせ、その後ec2.internalをサフィックスに付与してLink 2 (ens5)172.31.0.2へ問い合わせていることが分かります。

「ec2.internalのホストの名前解決」の場合は、Link 2 (ens5)に設定されているec2.internalと一致しているため直接Link 2 (ens5)172.31.0.2へ問い合わせていることが分かります。

なお、digはNSS(/etc/nsswitch.conf)の影響を受けないため、systemd-resolvedを使うように設定変更しても名前解決はできません。

# digによるec2.internalのホストのsearch確認
$ dig ip-10-0-1-10.ec2.internal +noall +answer +stats
;; Query time: 0 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Wed Apr 19 01:31:13 UTC 2023
;; MSG SIZE  rcvd: 129

# digによるec2.internalのホストの名前解決
$ dig ip-10-0-1-10 +noall +answer +stats +search
;; Query time: 0 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Wed Apr 19 01:35:50 UTC 2023
;; MSG SIZE  rcvd: 116

その際のWiresharkの結果からからもLink 2 (ens5)172.31.0.2へ問い合わせていないことが分かります。

  • digによるec2.internalのホストのsearch確認

systemd-resolved_running_nosearch_dig

  • digによるec2.internalのホストの名前解決

systemd-resolved_running_search_dig

次に、systemd-resolvedを停止させた状態でec2.internalのホストのsearchが上手く動作するのか確認します。

# systemd-resolved の停止
$ sudo systemctl stop systemd-resolved.service

# systemd-resolved が停止したことを確認
$ systemctl status systemd-resolved.service
○ systemd-resolved.service - Network Name Resolution
     Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; enabled; preset: enabled)
     Active: inactive (dead) since Tue 2023-04-18 09:25:06 UTC; 38s ago
   Duration: 4min 7.278s
       Docs: man:systemd-resolved.service(8)
             man:org.freedesktop.resolve1(5)
             https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
             https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
    Process: 1232 ExecStart=/usr/lib/systemd/systemd-resolved (code=exited, status=0/SUCCESS)
   Main PID: 1232 (code=exited, status=0/SUCCESS)
     Status: "Shutting down..."
        CPU: 136ms

Apr 18 09:20:58 ip-172-31-10-89.ec2.internal systemd[1]: Starting systemd-resolved.service - Network Name Resolution...
Apr 18 09:20:58 ip-172-31-10-89.ec2.internal systemd-resolved[1232]: Positive Trust Anchors:
Apr 18 09:20:58 ip-172-31-10-89.ec2.internal systemd-resolved[1232]: . IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d
Apr 18 09:20:58 ip-172-31-10-89.ec2.internal systemd-resolved[1232]: Negative trust anchors: home.arpa 10.in-addr.arpa 16.172.in-addr.arpa 17.172.in-addr.arpa 18.172.in-a>
Apr 18 09:20:58 ip-172-31-10-89.ec2.internal systemd-resolved[1232]: Using system hostname 'ip-172-31-10-89.ec2.internal'.
Apr 18 09:20:59 ip-172-31-10-89.ec2.internal systemd[1]: Started systemd-resolved.service - Network Name Resolution.
Apr 18 09:21:34 ip-172-31-10-89.ec2.internal systemd-resolved[1232]: Clock change detected. Flushing caches.
Apr 18 09:25:06 ip-172-31-10-89.ec2.internal systemd[1]: Stopping systemd-resolved.service - Network Name Resolution...
Apr 18 09:25:06 ip-172-31-10-89.ec2.internal systemd[1]: systemd-resolved.service: Deactivated successfully.
Apr 18 09:25:06 ip-172-31-10-89.ec2.internal systemd[1]: Stopped systemd-resolved.service - Network Name Resolution.

# ec2.internalのホストのsearch確認
$ ping ip-10-0-1-10 -c 1 | head -n1
ping: ip-10-0-1-10: Name or service not known

# ec2.internalのホストの名前解決
$ ping ip-10-0-1-10.ec2.internal -c 1 | head -n1
ping: ip-10-0-1-10.ec2.internal: Name or service not known

systemd-resolvedが起動していなければ名前解決に失敗することが分かりました。

Amazon Linux 2と設定方法が異なるので注意しよう

Amazon Linux 2023におけるDHCP option setsで設定したDNSサーバー以外のDNSサーバーを指定する方法を紹介しました。

Amazon Linux 2と設定方法が異なるので注意が必要です。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!