/etc/hosts と /etc/resolv.conf - 名前解決の優先順位

/etc/hosts と /etc/resolv.conf - 名前解決の優先順位

/etc/hosts と /etc/resolv.conf とは?

/etc/hosts はホスト名と IP アドレスの静的なマッピングを記述するローカルファイルで、DNS を経由せず即座に解決できる。/etc/resolv.conf は DNS リゾルバの設定ファイルで、参照するネームサーバを指定する。どちらを先に参照するかは /etc/nsswitch.confhosts: 行が制御し、デフォルトは files dns でホストファイルが DNS より優先される。

結論(名前解決の優先順位)

/etc/nsswitch.confhosts: files dns が意味するもの:

  1. /etc/hosts を検索(一致があれば即返す)
  2. DNS(/etc/resolv.conf に従う)を問い合わせ

名前解決はどのような流れで行われるのか?

Linux の名前解決は NSS(Name Service Switch)が統括する。/etc/nsswitch.conf を見ると、hosts: 行に解決ソースが優先順位付きで列挙されている。

$ grep ^hosts /etc/nsswitch.conf
hosts:          files mdns4_minimal [NOTFOUND=return] dns
  • files = /etc/hosts
  • mdns4_minimal = mDNS(Avahi)による .local ドメイン解決
  • dns = /etc/resolv.conf で指定したネームサーバ

解決フロー(デフォルト設定):

アプリが getaddrinfo("example.com") を呼ぶ
    ↓
1. /etc/hosts を検索
   → 一致あり: 即座にその IP を返す
   → 一致なし: 次へ
    ↓
2. DNS リゾルバ (/etc/resolv.conf の nameserver) に問い合わせ
   → 応答を返す

/etc/hosts の書式と活用パターン

書式

IPアドレス  ホスト名  [エイリアス ...]
$ cat /etc/hosts
127.0.0.1   localhost
127.0.1.1   myhost.local myhost
::1         localhost ip6-localhost ip6-loopback

開発環境でのドメイン上書き

本番ドメインをローカル IP に向けてテストする典型パターン:

# example.com をローカル開発サーバに向ける
127.0.0.1   example.com
127.0.0.1   api.example.com

不要なドメインのブロック

0.0.0.0 に向けるとそのドメインへの接続をブロックできる:

0.0.0.0     ads.example.com

/etc/hosts の変更は即座に反映される(DNS キャッシュのフラッシュ不要)。

/etc/resolv.conf の設定

主なディレクティブ

ディレクティブ 役割
nameserver 参照する DNS サーバの IP(最大3件)
search ホスト名補完ドメイン(db01db01.example.com
domain search の単一ドメイン版(旧来の設定)
$ cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
search example.com

Ubuntu での注意点 - systemd-resolved

Ubuntu 20.04 以降では /etc/resolv.confsystemd-resolved のスタブリゾルバへのシンボリックリンクになっている場合がある:

$ ls -la /etc/resolv.conf
lrwxrwxrwx 1 root root 39 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

この場合、resolv.conf を直接編集しても再起動で上書きされる。DNS 設定の変更は systemd-resolved 経由で行う:

# 現在の DNS 設定を確認
$ resolvectl status

# 特定インターフェースの DNS を設定
$ resolvectl dns eth0 8.8.8.8

/etc/resolv.conf が symlink かどうかは ls -la /etc/resolv.conf で確認できる。symlink なら直接編集せず resolvectl を使う。

優先順位を制御する /etc/nsswitch.conf

/etc/nsswitch.confhosts: 行を編集すると解決順序を変更できる。

# デフォルト(Ubuntu)
hosts: files mdns4_minimal [NOTFOUND=return] dns

# DNS を先にしたい場合(非推奨)
hosts: dns files

hosts: 行の変更はシステム全体の名前解決に影響する。変更前に元の値を記録しておくこと。

デバッグコマンド

getent hosts - nsswitch.conf を通じた解決確認

dignslookup は DNS のみ問い合わせる(/etc/hosts を経由しない)。getent hostsnsswitch.conf の設定に従って解決するため、OS が実際に何を返すかを確認できる。

# nsswitch.conf の設定に従って解決(hosts ファイルも含む)
$ getent hosts example.com
93.184.216.34   example.com

# /etc/hosts に書いたエントリが機能しているか確認
$ getent hosts myapp.local
127.0.0.1   myapp.local
# DNS のみ問い合わせ(hosts ファイルをバイパス)
$ dig example.com
$ nslookup example.com

# nsswitch.conf 経由(hosts ファイルも含む)
$ getent hosts example.com

resolvectl - systemd-resolved の状態確認

# DNS サーバと検索ドメインをインターフェース別に表示
$ resolvectl status

# 特定ドメインの DNS 解決をテスト
$ resolvectl query example.com

実践シナリオ

シナリオ 1: 開発環境で本番ドメインをローカルに向ける

# /etc/hosts に追記
$ sudo sh -c 'echo "127.0.0.1 api.myapp.com" >> /etc/hosts'

# 動作確認
$ getent hosts api.myapp.com
127.0.0.1   api.myapp.com

テスト後は削除する:

$ sudo sed -i '/api.myapp.com/d' /etc/hosts

シナリオ 2: カスタム DNS サーバに切り替える

systemd-resolved を使用していない環境(静的な resolv.conf の場合):

$ sudo nano /etc/resolv.conf
# 以下を追加または変更
nameserver 1.1.1.1   # Cloudflare DNS
nameserver 8.8.8.8   # Google DNS

確認:

$ dig @1.1.1.1 example.com

まとめ - 名前解決チェックリスト

確認項目 コマンド
解決順序 grep ^hosts /etc/nsswitch.conf
hosts ファイルの内容 cat /etc/hosts
DNS リゾルバ設定 cat /etc/resolv.conf
resolv.conf の symlink 確認 ls -la /etc/resolv.conf
DNS 設定の確認(Ubuntu) resolvectl status
名前解決テスト(hosts 含む) getent hosts <ドメイン>
DNS のみテスト dig <ドメイン>

よくあるトラブル

  • getent hosts では解決できるが dig / nslookup では解決できない → /etc/hosts に書いたエントリが有効
  • 両方で解決できない → DNS 設定か resolv.conf の問題
  • Ubuntu で resolv.conf を編集しても再起動後に戻る → systemd-resolved が管理しているため resolvectl で変更する

次に読む