2026年5月30日

2026年5月30日

Linuxのresolv.confの設定方法|名前解決が遅い・ときどき失敗するときのoptions調整

Linux サーバーで名前解決が遅い、ときどき失敗するといった問題は、/etc/resolv.conf の nameserver の並びと options 行(timeout・attempts・rotate・single-request-reopen・ndots など)の調整で改善できることが多くあります。ただし、効く設定は症状によって違い、ファイルの管理元によって書く場所も変わります。この記事では、遅さを測って原因の型を見分ける方法、型ごとに効く options、systemd-resolved・NetworkManager・Docker での設定の入れ方、WordPress から見た確認方法を解説します。

まず遅さを測る

設定を変える前に、どのくらい遅いのか、毎回なのかを数字で確かめます。

# glibc の名前解決にかかる時間(/etc/hosts も含めアプリと同じ経路)
time getent ahosts api.wordpress.org

# resolv.conf に書かれた DNS サーバーを1台ずつ測る(Query time を見る)
grep '^nameserver' /etc/resolv.conf
dig @192.0.2.53 api.wordpress.org +stats | grep 'Query time'

# PHP から見た名前解決
time php -r 'var_dump(gethostbynamel("api.wordpress.org"));'

結果は次のように読みます。

  • 毎回ほぼ5秒、または10秒前後かかる:1回の待ち時間(既定は5秒)を使い切ってから次へ進んでいる型です。応答しない nameserver があるか、問い合わせの応答が途中で失われています
  • dig では速いのに getent や PHP だけ遅い:search ドメインの補完、/etc/hosts、IPv6 の扱いなど、DNS サーバー以外の経路を疑います
  • ときどきだけ失敗する:複数の nameserver のうち一部が不調、あるいは負荷時にだけ応答が遅れている型です

遅さの型と効くoptions

1台目のnameserverが応答しない

glibc は nameserver を書いた順に使い、1台目が応答しないと待ち時間が過ぎてから2台目に移ります。毎回の名前解決にその秒数が上乗せされるため、最初の対処は応答しないサーバーを外すか、並びを入れ替えることです。

そのうえで、待ち時間と試行回数を短めに調整できます。

nameserver 192.0.2.53
nameserver 198.51.100.53
options timeout:2 attempts:3

timeout は1回の問い合わせの待ち秒数(既定5、上限30)、attempts は全サーバーを一巡する回数(既定2、上限5)です。短くしすぎると、遠い DNS サーバーの正常な応答まで失敗扱いになるので、測った Query time に十分な余裕を持たせます。rotate を加えると問い合わせ先を順番に振り分けますが、壊れたサーバーを避ける仕組みではないため、不調なサーバーを残したまま使うと、かえって失敗が分散して見えにくくなります。

A と AAAA の同時問い合わせの応答が失われる

glibc は既定で A(IPv4)と AAAA(IPv6)の問い合わせを同じソケットから続けて送ります。途中のファイアウォールや NAT の実装によっては片方の応答が捨てられ、待ち時間の5秒を使い切ってから再送する、という遅れ方をします。毎回きっちり5秒遅れるなら、この型を疑います。

options single-request-reopen

single-request-reopen は、問題が起きたときに AAAA 用のソケットを開き直して送ります。それでも改善しない場合は、A と AAAA を順番に1つずつ送る single-request を試します。根本的には、途中の機器の設定を見直すのが本筋です。

search と ndots で余計な問い合わせが増える

search に複数のドメインを書くと、ドットの少ない名前を引くときに補完した名前から順に問い合わせ、存在しない名前の問い合わせ(NXDOMAIN)が何度も発生します。どの名前をそのまま先に問い合わせるかは ndots(既定1)で決まり、値を大きくするほど外部の名前にも補完が付きやすくなります。

  • 使っていない search ドメインは削除する
  • ndots を大きくしている環境(Kubernetes では大きめの値が既定になっていることがあります)では、外部の名前を末尾にドットを付けた完全修飾名で書くと、補完を飛ばせます

IPv6の経路が無いのにAAAAが返る

これは DNS ではなく接続の問題ですが、症状は「名前解決が遅い」に見えます。サーバーに IPv6 の経路が無いのに、相手先が AAAA を返すと、プログラムが先に IPv6 で接続しようとして待たされます。/etc/gai.conf で precedence ::ffff:0:0/96 100 の行を有効にすると IPv4 を優先させられます。新しい glibc には AAAA の問い合わせ自体を止める no-aaaa オプションもありますが、使える版かどうかを man resolv.conf で確認してください。

毎回遠くのDNSに問い合わせている

resolv.conf だけの構成では、同じ名前でも毎回 DNS サーバーへ問い合わせます。外部 API を頻繁に呼ぶサーバーでは、systemd-resolved、Unbound、dnsmasq などのローカルのキャッシュを使うと、往復の時間を省けます。

管理元ごとの設定の入れ方

resolv.conf が自動生成されている環境では、直接書いた options は再起動や DHCP の更新で消えます。ls -l /etc/resolv.conf と先頭のコメントで管理元を確かめ、次の場所で設定します。どの場合も、変更前に現在のファイルを控えておきます。

systemd-resolved(Ubuntu の既定構成など):resolv.conf にはローカルのスタブ 127.0.0.53 が書かれ、問い合わせ先の切り替えや再送は systemd-resolved 側が行います。この構成では resolv.conf の timeout などはスタブへの問い合わせにしか効かないため、遅さの対処は /etc/systemd/resolved.conf.d/ に置いた設定で、応答しない上流サーバーを DNS= から外すことが中心になります。resolvectl status で使われている上流サーバーを、resolvectl statistics でキャッシュの効き具合を確認できます。

NetworkManager(RHEL 系など):接続ごとの設定として options を指定できます。

sudo nmcli con mod "System eth0" ipv4.dns-options "timeout:2 attempts:3 single-request-reopen"
sudo nmcli con up "System eth0"

接続名は nmcli con show で確認して読み替えます。nmcli con up は接続を張り直すため、リモートから作業するときは内容をよく確認してから実行します。

管理元の無い構成:resolv.conf を直接編集して構いません。glibc 2.26 以降は、ファイルの変更を検知して読み直します。

Docker・Docker Compose:コンテナの resolv.conf は Docker が生成するため、docker run の --dns-opt、Compose の dns_opt で options を渡します。

services:
  wordpress:
    image: wordpress
    dns_opt:
      - timeout:2
      - single-request-reopen

Alpine Linux ベースのイメージは glibc ではなく musl を使っており、名前解決の挙動が異なるうえ、ここで挙げた options の一部は効きません。

変更を試し、効果を確認する

options は、環境変数 RES_OPTIONS でコマンド単位に試せます。設定ファイルを変える前に効果を確かめるのに便利です。

RES_OPTIONS="timeout:2 attempts:3 single-request-reopen" bash -c 'time getent ahosts api.wordpress.org'

設定を反映したら、最初と同じ測り方で時間を比べます。PHP-FPM のような常駐プロセスは、念のため再起動して読み直させます。サービス名は PHP の版やディストリビューションで異なるので、systemctl list-units | grep fpm で確認してください。

WordPress から外部への通信が改善したかは、WP-CLI で確かめられます。

time wp eval 'var_dump( wp_remote_retrieve_response_code( wp_remote_get( "https://api.wordpress.org/core/version-check/1.7/" ) ) );'

200 が返り、時間が短くなっていれば、プラグインの更新確認や外部 API を使う機能の待ち時間も短くなります。管理画面の「サイトヘルス」に外部との通信やループバック要求の失敗が出ていた場合は、あわせて表示が変わるかを確認します。表示される項目名は WordPress の版によって異なります(2026年10月現在)。

まとめ

  • 設定を変える前に getent・dig +stats・PHP で時間を測り、遅れ方の型を見分ける
  • 毎回の待ち時間は応答しない nameserver を外し、timeout・attempts を測定値に合わせて調整する
  • きっちり5秒の遅れには single-request-reopen、余計な補完には search と ndots の見直しが効く
  • 自動生成の環境では、systemd-resolved・NetworkManager・Docker それぞれの設定で指定する
  • RES_OPTIONS で事前に試し、WP-CLI で WordPress からの通信まで確認する

お気軽にご相談ください

お見積りへ お問い合わせへ
▲