DNSとは?ドメインがVPSに届かない原因と確認方法
DNSはドメインがVPSへ届くかを左右します。レコード、ネームサーバー、TTLと、変更が失敗したように見えるキャッシュの仕組みを順番に確認できます。
DNS とは何か、ドメインがまだ VPS に到達しない理由
DNS(ドメインネームシステム)は、example.com のような名前を、203.0.113.10 のような IP(インターネットプロトコル)アドレスに変換します。ブラウザーは名前に接続できません。アドレスに接続するため、ページを読み込むたびに DNS への問い合わせと応答が発生します。ドメインを購入したばかりで、自分で運用する VPS も用意したのに何も表示されない場合、考えられるのは次のどちらかです。名前をサーバーのアドレスへ接続するレコードがまだないか、レコードはあるものの、経路上の何かが古い応答を返し続けています。
どちらも正常に起こる状況であり、何かが壊れていることを意味しません。以下のセクションでは、実際に確認する順番に沿って説明します。最初に扱うのは、最も時間を浪費しやすい問題です。つまり、レコードを実際に管理しているコントロールパネルを特定することです。
ここで行うすべての確認では dig を使用します。dig は、初期状態の Ubuntu または Debian マシンにはデフォルトでインストールされていません。
sudo apt update && sudo apt install -y bind9-dnsutilsレジストラ、ネームサーバー、DNS ホスト: どれを編集するか
この3つは、それぞれ異なる役割を指します。混同すると、編集しても何も変わらないことが最も多くあります。
- レジストラは、ドメインを購入した会社です。重要な役割は委任です。TLD(トップレベルドメイン。
.comの部分)を管理するレジストリに対し、ドメインの権威ネームサーバーを通知します。 - 権威ネームサーバーは、ゾーンの実際のレコードを保持します。ゾーンとは、ドメインとその配下の名前を指します。
- DNS ホストは、そのネームサーバーを運用する事業者です。レジストラ自身の場合もあれば、別のプロバイダーの場合や、所有するサーバー上で
bind9を運用している場合もあります。
ドメインはレジストラで購入します。編集は DNS ホストで行います。ドメインを別のプロバイダーのネームサーバーへ移行した場合、レジストラの DNS パネルには引き続きゾーンが表示され、編集内容も保存されます。しかし、インターネット上の誰もそのゾーンに問い合わせません。レコードは実在しています。ただし、参照されることがありません。
世界中からどこへ問い合わせているかを確認します。
dig example.com NS +short
dig +trace example.com最初のコマンドは、現在そのドメインへの応答に使用されているネームサーバーを表示します。2つ目のコマンドは、root server から始めて DNS の委任チェーンをたどり、TLD サーバーが返す委任情報を表示します。これは、レジストラが管理する委任です。表示された名前が認識できないプロバイダーのものであれば、必要なパネルはそのプロバイダーが提供しています。
1 回の名前解決がたどる経路
関係する主体は 4 つあり、それぞれが取得した情報のコピーを保持します。
- スタブリゾルバーは、使用中のマシン上で動作します。検索は行いません。設定された 1 台のサーバーに問い合わせ、その応答を信頼します。Ubuntu では、
/etc/resolv.confは通常/run/systemd/resolve/stub-resolv.confへのシンボリックリンクであり、ローカルで独自のキャッシュを持って動作するsystemd-resolvedである127.0.0.53を指します。 - 再帰リゾルバーは、ISP(インターネットサービスプロバイダー)が運用するリゾルバー、
1.1.1.1のようなパブリックリゾルバー、または自分で運用するリゾルバーです。実際に答えを検索する役割を担います。 - ルートサーバーと TLD サーバーです。再帰リゾルバーはルートサーバーに問い合わせます。ルートサーバーはアドレスを知りませんが、
.comサーバーへの委任を返します。.comサーバーは、さらに権威ネームサーバーへの委任を返します。 - 権威ネームサーバーは、他のサーバーには問い合わせません。自身のゾーンから応答し、その応答が権威あるものであることを示します。
dig +trace example.com は、キャッシュに問い合わせずルートから処理を開始し、各委任を表示するため、この流れを確認できます。委任とゾーンの内容が一致しているかを確認するには、これが最も迅速な方法です。
サーバー運用で重要な DNS レコード
A: 名前を IPv4 アドレスに対応付けます。example.com. A 203.0.113.10。ドメインを VPS に向けるレコードです。AAAA: 名前を IPv6 アドレス(2001:db8::10など)に対応付けます。そのアドレスでサービスが実際に待ち受ける場合だけ公開します。IPv6 ネットワーク上のクライアントは最初に AAAA の応答を試すため、応答するサービスがないアドレスを設定すると、アクセスのたびに遅延が発生します。CNAME: ある名前から別の名前へのエイリアスです。www.example.com. CNAME example.com.はwwwへの訪問者を、ベアドメインが解決する宛先へ送ります。CNAME は apex(ベアドメインのexample.com)には配置できません。apex には独自の SOA(start of authority)レコードと NS レコードが必要であり、CNAME は他のレコードと同じ名前を共有できないためです。プロバイダーは ALIAS、ANAME、CNAME flattening などの名前で回避策を提供しています。MX: ドメイン宛てのメールの配送先です。ホスト名と preference 番号を持ち、番号が小さいものから試されます。MX はアドレスレコードを持つ名前を指定する必要があります。CNAME を指定するのは無効であり、送信側サーバーによっては拒否されます。TXT: 証明やポリシーに使用する自由形式のテキストです。メール認証レコード(SPF、DKIM、DMARC)や、ワイルドカード証明書を発行する ACME(automatic certificate management environment)トークンはここに配置します。NS: ゾーンを提供する nameserver を指定します。インターネット上の問い合わせ先を決めるコピーは親ゾーンにあり、独自ゾーン内のコピーではなく、レジストラの委任情報から取得されます。
レコードの種類そのものより混乱しやすい点が2つあります。末尾がドットの名前は絶対名です。そのため、www.example.com. はその名前だけを正確に意味します。多くの管理パネルは相対名を想定し、ドメインを自動的に追加します。そのため、名前欄に www.example.com と入力すると www.example.com.example.com になり、誰も解決できません。もう1つは @ です。ほぼすべての管理パネルで、これは apex、つまりサブドメインのないドメインそのものを意味します。
VPS を A レコードに設定する
まず、インターネットから見えるサーバーのアドレスを取得します。
curl -4 https://ifconfig.me
ip -brief -4 address show次に、DNS ホストでレコードを 1 つ作成します。タイプは A、名前は @、値はそのアドレス、TTL(time to live)は 300 にします。www 用の 2 つ目のレコードも追加します。同じアドレスを指定する別の A にするか、apex を指す CNAME にします。
次に、名前解決を確認します。できればサーバー自体ではなく、ラップトップから実行してください。
dig example.com A +short
dig @1.1.1.1 example.com A +short
dig @ns1.your-dns-host.net example.com A +short1 つ目は、キャッシュを含む、使用中のマシンの通常の経路を使います。2 つ目はローカルキャッシュを使用せず、パブリックな再帰リゾルバーに問い合わせます。3 つ目は権威ネームサーバーに直接問い合わせるため、経路上のキャッシュを介さない現在の正しい応答を取得できます。3 つ目のコマンドがアドレスを返し、1 つ目が返さない場合、DNS は正しく設定されています。古い応答のキャッシュが残っている状態です。
名前解決は読み込みではありません
名前解決が成功すれば、DNS が機能していることを確認できます。ただし、Web サーバーが機能していることは確認できません。dig が正しいアドレスを返したら、接続をテストします。
curl -I http://example.comcurl: (6) Could not resolve host: example.com は DNS の問題です。curl: (7) Failed to connect to example.com port 80 after 21 ms: Connection refused は DNS の問題ではありません。名前解決が成功し、パケットも到達しているため、そのポートで待ち受けているものがないことが原因です。要求がハングアップした後にタイムアウトする場合は、接続を拒否する代わりに、ファイアウォールがパケットを破棄していることが一般的です。ここで DNS の確認は終わり、ポートと待ち受けソケット、および VPS の ufw ファイアウォールルールを確認します。接続が確立した後のページ読み込みは、HTTP の処理です。
ブラウザーに古いホストが表示され続ける理由
変更内容が外部へ伝播することはありません。サーバーが変更を他の利用者へ送信するわけではありません。権威ネームサーバーは、保存した瞬間に新しい値を保持します。一方、以前の応答のキャッシュは、それぞれのタイマーが切れるまで有効です。このタイマーが TTL です。レコードが応答として返された時点の TTL が秒単位で設定されています。
キャッシュされたコピーは、想定より多くの場所に存在します。ブラウザー自身の短期キャッシュ、マシン上の stub resolver、そのネットワークが使用する再帰リゾルバー、クライアントに VPN が設定したリゾルバーなどです。それぞれが、受け取った TTL の期間だけコピーを保持します。2 つのネットワークにいる 2 人の利用者が、数時間にわたって異なる応答を確認することもあります。どちらのマシンも正常に動作しています。
キャッシュリゾルバーに対するカウントダウンを確認します。
dig @1.1.1.1 example.com +noall +answer数秒間隔で 2 回実行します。応答内の TTL が減少します。TTL が 0 になると、リゾルバーはレコードを破棄し、ネームサーバーへ再度問い合わせます。
ほとんど誰も考慮しない 2 つ目のキャッシュがあります。否定応答のキャッシュです。名前が存在しないとリゾルバーに通知されると、その NXDOMAIN もキャッシュされます。キャッシュ期間は、ゾーンの SOA レコードの最後のフィールドで指定された時間です。
dig example.com SOA +shortこの行の最後の数値が負の TTL で、多くの場合は 3600 です。そのため、作成前に staging.example.com を検索すると、作成後も 1 時間にわたってレコードが表示されないことがあります。先にレコードを作成してから、検索してください。
ネームサーバーの変更がレコードの変更より遅いのは、仕組みによるものです。.com ゾーンの委任レコードは TTL 172800 秒、つまり 2 日で提供されます。そのため、古いネームサーバーをキャッシュしたリゾルバーは、その期間にわたって古いネームサーバーへ問い合わせ続けることがあります。「最大 48 時間かかる場合がある」という説明は、ここから来ています。これはネームサーバーの変更に適用されるもので、通常のレコード編集には適用されません。
TTL に逆らうのではなく、TTL を基準に移行を計画します。
- レコードの TTL を 300 に下げて保存します。
- 古い TTL より長く待ち、古い値を保持するすべてのキャッシュが期限切れになるのを待ちます。
- アドレスを変更します。
- トラフィックの移行後、TTL を 3600 以上に戻します。TTL が低いと、すべてのリゾルバーがネームサーバーへより頻繁に問い合わせるためです。
自分のマシンが保持しているキャッシュを消去するには、次の操作を行います。
resolvectl flush-caches
resolvectl statisticsresolvectl statistics は、hit と miss のカウンターを含むキャッシュセクションを出力します。そのため、flush の直後に行った検索は miss として表示されます。ブラウザーは別のキャッシュを保持します。システムキャッシュを空にしても、Chrome が古い応答を使用することがあります。chrome://net-internals/#dns でそのキャッシュも消去してください。/etc/hosts も確認してください。そこに残った行は、そのマシン上でのみ DNS より優先されます。getent hosts example.com は、システムが実際に使用する応答を表示します。/etc/hosts も含まれます。
ワイルドカード証明書は TXT レコードで所有権を証明します
CA(認証局)は、証明書を発行する前にドメイン名を管理していることを確認します。HTTP-01 チャレンジでは、対象ホスト名のポート 80 でファイルを配信します。これは単一の名前に適しています。ワイルドカード証明書は *.example.com を対象とします。これはホスト名の範囲に上限がなく、CA がファイルを取得できないため、Let's Encrypt は DNS-01 チャレンジでのみワイルドカード証明書を発行します。_acme-challenge.example.com に、CA から提供されたトークンを含む TXT レコードを公開します。ゾーンを管理していることが証明になります。
そのため、DNS ホストは証明書の更新処理に含まれます。Certbot は更新のたびに、ユーザーの操作なしでその TXT レコードを作成・削除する必要があります。そのため、DNS プロバイダーの API と対応するプラグインが必要です。検証に失敗すると、通常は DNS problem: NXDOMAIN looking up TXT for _acme-challenge.example.com というメッセージが表示されます。これは、レコードが DNS から参照できるようになる前に CA が問い合わせたことを意味します。レコードが保存されていないか、否定応答がまだキャッシュされていた可能性があります。手順の詳細は、DNS-01 チャレンジでワイルドカード証明書を取得するガイドにあります。
VPN がリゾルバーを引き継ぐ場合
VPN(仮想プライベートネットワーク)クライアントは、通常、接続中にシステムのリゾルバーを置き換えます。ローカルネットワークへ名前解決を送信すると、アクセスしたすべてのサイト名をそのネットワークに知られるためです。これは正しい動作ですが、2 つの問題が起こり得ます。
トンネルが確立した後、アドレスには接続できるのに名前解決が停止する場合は、クライアントが設定したリゾルバーにトンネル内部から到達できません。ping 1.1.1.1 は成功し、curl https://example.com は curl: (6) Could not resolve host: example.com を返します。一方、トンネルが確立した後も、接続中のネットワークへ名前解決が送信される場合は、トラフィックはトンネル経由になりますが、ローカルリゾルバーには要求したすべての名前が見え続けます。
resolvectl statusこのコマンドは、各リンクで使用中のリゾルバーを表示します。トンネルが設定したリゾルバーと、それが意図したものかどうかを確認できます。WireGuard トンネルでは、クライアント設定の DNS = 行でこの値を設定します。systemd-resolved と resolvconf のケースについては、WireGuard がリゾルバーを引き継いだときの DNS の修正で詳しく説明しています。
応答コードと、それぞれが示す内容
NXDOMAIN: 権威サーバーが、その名前は存在しないと示しています。スペルを確認し、ドメインサフィックスが重複していないか確認します。また、委任先が指定しているゾーンを編集したか確認します。NOERRORと空のANSWER SECTION: その名前は存在しますが、要求した種類のレコードはありません。Aしか存在しない名前に対してAAAAを問い合わせると、まさにこの結果になります。SERVFAIL: リゾルバーが処理を試みましたが、応答を生成できませんでした。一般的な原因は、権威サーバーが応答しないことと、DNSSEC(domain name system security extensions)の検証に失敗することです。検証を無効にするdig @1.1.1.1 example.com A +cdを使ってテストします。これを付けない場合に+cdとSERVFAILを伴う応答が得られるなら、問題は署名にあります。これは、ネームサーバーを移行した後も親ゾーンが古い DS(delegation signer)レコードを公開している場合に発生します。REFUSED: 問い合わせ先のサーバーが、その問い合わせには応答しません。通常は、提供していないドメインの権威サーバーに対してdigを実行しています。;; connection timed out; no servers could be reached: dig がリゾルバーに到達していません。これは手元のネットワークまたはリゾルバーの問題であり、ドメイン自体が原因ではありません。
ping: example.com: Temporary failure in name resolution は、dig ではなく glibc が報告する同じ種類の失敗です。
自分の VPS でネームサーバーを運用すべきですか?
可能です。bind9、knot、nsd を使えば、サーバーからゾーンを提供できます。DNS について、どのコントロールパネルよりも深く学べます。問題は実際の運用です。ドメインには、別々のネットワーク上に少なくとも 2 台のネームサーバーを置く必要があります。そのため、VPS が 1 台だけの場合、メールを含むドメイン上のすべてのサービスに対する単一障害点になります。提供対象のドメイン内にあるネームサーバーには、レジストラ側でグルーレコードが必要です。これは親ゾーンに保存された ns1.example.com のアドレスです。これがないと、名前解決を開始できません。リゾルバーがネームサーバーに接続できない場合、Web サイトへフォールバックすることはありません。そのユーザーからは、ドメイン全体が利用できなくなります。多くのユーザーにとっては、API を利用できるホステッド DNS のほうがリスクの低い選択肢です。自分のマシン向けに VPS 上でキャッシュリゾルバーを運用するのは別の用途であり、必要な運用負担もはるかに小さくなります。
FAQ
DNS 変更がまだ反映されないのはなぜですか?
反映処理が行われるわけではありません。権威ネームサーバーは、変更を保存した時点で新しい値を保持します。すでに問い合わせを行った各リゾルバーは、受け取った TTL が期限切れになるまでキャッシュした値を保持します。dig @ns1.your-dns-host.net example.com A +short で権威サーバーに直接問い合わせてください。新しいアドレスが返れば、変更は有効で、残る問題はキャッシュだけです。レコードではなくネームサーバーを変更した場合は、TLD の委任情報が 2 day の TTL で配布されるため、反映にかなり時間がかかります。
ドメインが実際に使用しているネームサーバーを確認するにはどうすればよいですか?
dig example.com NS +short は、その時点でドメインに応答しているネームサーバーを表示します。dig +trace example.com は root からの委任チェーンを表示し、TLD サーバーが配布している委任情報も確認できます。表示された名前が、編集に使用しているプロバイダーのものではない場合、そこが原因です。委任情報で指定されているプロバイダーでレコードを編集するか、レジストラで委任先を変更して、目的のプロバイダーを指定してください。
ドメインは名前解決できますが、サイトが読み込まれません。どうすればよいですか?
dig example.com A +short がサーバーのアドレスを返した時点で、DNS の処理は完了しています。その後の問題は接続です。curl -I http://example.com が Connection refused を返す場合、そのポートで待ち受けているサービスはありません。リクエストがタイムアウトするまで停止する場合は、ファイアウォールがパケットを破棄しています。Web サーバーが起動し、パブリックアドレスにバインドしていることを確認してください。続いて、サーバー上のファイアウォールと、プロバイダーのコントロールパネルにある別のネットワークファイアウォールを確認します。
ルートドメインに CNAME を設定できないのはなぜですか?
CNAME は、ある名前が別の名前のエイリアスであることを示します。CNAME を持つ名前には、他のレコードを設定できません。ルートドメインはゾーンとして存在するために SOA レコードと NS レコードを持つ必要があるため、同時に CNAME にすることはできません。ルートにアドレスを格納する A レコードを使用してください。または、ALIAS、ANAME、CNAME flattening などの名前で提供されているプロバイダー機能を使用します。この機能は名前を保存し、その名前が現在名前解決するアドレスを使ってクエリに応答します。