/etc/hosts と /etc/resolv.conf - 名前解決の優先順位
/etc/hosts と /etc/resolv.conf とは?
/etc/hosts はホスト名と IP アドレスの静的なマッピングを記述するローカルファイルで、DNS を経由せず即座に解決できる。/etc/resolv.conf は DNS リゾルバの設定ファイルで、参照するネームサーバを指定する。どちらを先に参照するかは /etc/nsswitch.conf の hosts: 行が制御し、デフォルトは files dns でホストファイルが DNS より優先される。
結論(名前解決の優先順位)
/etc/nsswitch.conf の hosts: files dns が意味するもの:
/etc/hostsを検索(一致があれば即返す)- 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/hostsmdns4_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 |
ホスト名補完ドメイン(db01 → db01.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.conf が systemd-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.conf の hosts: 行を編集すると解決順序を変更できる。
# デフォルト(Ubuntu) hosts: files mdns4_minimal [NOTFOUND=return] dns # DNS を先にしたい場合(非推奨) hosts: dns files
hosts: 行の変更はシステム全体の名前解決に影響する。変更前に元の値を記録しておくこと。
デバッグコマンド
getent hosts - nsswitch.conf を通じた解決確認
dig や nslookup は DNS のみ問い合わせる(/etc/hosts を経由しない)。getent hosts は nsswitch.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で変更する