クライアント側のDNS設定
Linuxマシンがexample.comのようなホスト名からIPアドレスを求める処理を名前解決と呼びます。この主題は、クライアント側(DNSサーバーそのものではなく、DNSサーバーに問い合わせる側)で名前解決がどのように行われるかを構成・確認・デバッグするための知識をまとめたものです。大きく分けると、次の4つの観点があります。
- リモートのDNSサーバーに直接問い合わせて結果を確認する(
host・dig)。 - どのDNSサーバーに問い合わせるかをローカルで設定する(
/etc/resolv.conf)。 - DNS以外の情報源(ローカルファイル等)も含めて、名前解決をどの順序で試すかを設定する(
/etc/nsswitch.conf・/etc/hosts・getent)。 - 上記を踏まえて、名前解決がうまくいかないときにどう切り分けるか。
リモートDNSサーバーへの問い合わせ
dig、host、nslookupは、DNSサーバーへ問い合わせて名前解決結果やDNSレコードを確認するコマンドです。DNSサーバーを明示すると、/etc/resolv.confの設定よりも指定したサーバーが使用されます。
| コマンド | 基本書式 | 192.168.0.10へMXレコードを問い合わせる例 |
|---|---|---|
dig | dig [@DNSサーバー] 対象 レコードタイプ | dig @192.168.0.10 example.com MX |
host | host -t タイプ 対象 [DNSサーバー] | host -t MX example.com 192.168.0.10 |
nslookup | nslookup -type=タイプ 対象 [DNSサーバー] | nslookup -type=MX example.com 192.168.0.10 |
digではDNSサーバーを先頭に@付きで指定しますが、hostとnslookupではDNSサーバーを末尾に指定します。 digとhostでレコードタイプを省略した場合、通常はAレコードが問い合わせられます。
DNSサーバーを省略した場合は、いずれも通常/etc/resolv.confに設定されたDNSサーバーを使用します。
ローカルの名前解決設定:/etc/resolv.conf
/etc/resolv.confは、問い合わせ先のDNSサーバーや、名前解決に関する既定の動作を設定するファイルです。主な設定項目は次のとおりです。
nameserver:問い合わせ先のDNSサーバーのIPアドレスを指定します。複数行書くことができ、上から順に問い合わせに使われます。search:ホスト名の一部だけを指定した場合(例:www)に、末尾に補って完全なホスト名にするドメイン名の候補を指定します。options:名前解決のタイムアウト時間など、細かい動作を調整するオプションです。
多くの環境では、このファイルを直接手で編集して運用しますが、後述するsystemd-resolvedやネットワーク管理サービス(NetworkManager等)が有効な環境では、/etc/resolv.confがそれらのサービスによって自動生成・上書きされる場合があります。「/etc/resolv.confを手で編集すれば必ずその内容が使われ続ける」とは限らない点に注意してください。
名前解決の実行順序の変更:nsswitch.conf・hosts・getent
DNSサーバーへの問い合わせは、名前解決の方法の1つに過ぎません。Linuxでは、名前解決に限らずユーザー情報やグループ情報なども含めて、どの情報源をどの順序で参照するかを一元的に管理する仕組みが用意されています。
/etc/nsswitch.conf
/etc/nsswitch.conf(Name Service Switch)は、ホスト名の解決やユーザー情報の参照など、種類ごとに「どの情報源を、どの順序で確認するか」を設定するファイルです。ホスト名の名前解決に関する設定はhostsから始まる行で行います。
hosts: files dns上記の例は、「まずfiles(/etc/hosts)を確認し、そこで見つからなければdns(DNSサーバーへの問い合わせ)を試す」という意味です。情報源は左から順に確認され、いずれかの情報源で結果が得られた時点で、既定ではそれ以降の情報源は確認されません各情報源の結果(成功・未検出・利用不可等)ごとに、次に進むか打ち切るかの既定の挙動が定義されており、\[NOTFOUND=return\]のような記法でその既定の挙動を明示的に上書きすることもできます。本記事では出題範囲に明記されている基本的な考え方(左から順に確認し、見つかった時点で確定する)にとどめ、この記法自体の詳細は範囲外とします。[1]。
/etc/hosts
/etc/hostsは、ホスト名とIPアドレスの対応をローカルに静的に記述するファイルです。
127.0.0.1 localhost
192.168.1.10 webserver.example.com webserver書式は「IPアドレス 正式なホスト名 別名」で、空白またはタブで区切ります。
上記では、webserverまたはwebserver.example.comが192.168.1.10に名前解決されます。 /etc/nsswitch.confがhosts: files dnsなら、DNSより先にこのファイルが参照されます。
確認にはgetent hosts webserverを実行し、表示されたIPアドレスを確認します。
getent
getentは、/etc/nsswitch.confに設定された順序に従って、実際にシステムが名前解決を行った場合と同じ結果を確認できるコマンドです。
getent hosts example.comここがhost・digとの重要な違いです。host・digは/etc/hostsや/etc/nsswitch.confの設定を経由せず、指定したDNSサーバーに直接問い合わせます。一方getentは、/etc/nsswitch.confで設定された順序(/etc/hostsを先に見るか、DNSを先に見るか等)をそのまま反映した、システムが実際に使う名前解決の結果を確認できます。
名前解決に関するエラーのデバッグ
名前解決がうまくいかないとき、getentとhost・digを使い分けることで、問題がどこにあるかを切り分けやすくなります。
getent hosts <ホスト名>の結果と、dig <ホスト名>(DNSサーバーに直接問い合わせた結果)が食い違う場合:/etc/hostsに古い・誤ったエントリが残っている、または/etc/nsswitch.confの順序設定が意図と異なっている可能性があります。dig・hostでDNSサーバーに直接問い合わせても結果が得られない・エラーになる場合:/etc/resolv.confに設定されているDNSサーバーのIPアドレスが誤っている、DNSサーバー自体に到達できない、DNSサーバー側で該当のレコードが存在しない、といった可能性を考えます。
このように、「システムが実際に使う名前解決の結果(getent)」と「DNSサーバーへの問い合わせそのものの結果(dig・host)」を分けて確認することが、デバッグの基本的な考え方になります。
systemd-resolvedの知識
systemd-resolvedは、systemdに含まれる名前解決サービスで、多くの現行ディストリビューションで既定のDNS解決の仕組みとして採用されています。systemd-resolvedが有効な環境では、/etc/resolv.confが固定の設定ファイルではなく、systemd-resolvedが提供するローカルのスタブリゾルバ(多くの環境で127.0.0.53)を指すシンボリックリンクとして構成される場合があります。この場合、実際のDNSサーバーへの問い合わせはsystemd-resolvedが代行し、キャッシュも行います。
補足
- 各情報源の結果(成功・未検出・利用不可等)ごとに、次に進むか打ち切るかの既定の挙動が定義されており、
\[NOTFOUND=return\]のような記法でその既定の挙動を明示的に上書きすることもできます。本記事では出題範囲に明記されている基本的な考え方(左から順に確認し、見つかった時点で確定する)にとどめ、この記法自体の詳細は範囲外とします。 ↩