hisamounaのブログ

アウトプットを習慣化するためのブログ

DNSがよくわかる教科書を読んだついでに、DNSについて色々と調べてみました

www.amazon.co.jp

年末年始でゆっくり本を読むことができたので、DNSについて改めて勉強しました。

こちらの本はDNSの基礎や運用していく上での知識などを体系的に学ぶことができ大変おすすめです。

以下、学んだことを書きつつ、DNSについて色々と調べてみました。

DNSが作られた背景

IPアドレスは「通信したい相手の指定」と「通信してきた相手の判別」に使われます。

通信相手の指定をIPアドレスで行うと、数字の羅列のため覚えづらく使いにくいです。

その問題を解消させるために、ホストの指定を名前(ドメイン名)で行えるようにするのに開発された システムが DNS です。

IPアドレスドメイン名があることで、システムの移行においてもメリットがあると感じました。

ドメイン名に紐づくIPアドレスを変更することで、システムの移行をクライアント側の手続きなしで行えるようになります。

IPアドレスでアクセスされている場合は、新しいシステムのIPアドレスを参照するようにクライアントに対応を依頼する必要があります。

リソースレコード

ドメイン名にIPアドレスの情報を設定する際は、IPv4IPv6の2種類それぞれ必要に応じてAリソースレコードとAAAAリソースレコードを設定します。

また、CNAMEリソースレコードを使うことで、ドメイン名に別のドメイン名を設定できます。

クラウドサービスではさらに便利な仕組みがあります。

例えば、AWSではalias recordがあります。

これを使い、Route53のドメインにA/AAAAリソースレコードにELBのドメイン名をセットします。

Route53ドメインの名前解決を試みると、ELBのIPアドレスが複数返却されます。

この仕組みにより、Route53を設定する人がELBのIPアドレスを気にする必要がなくなるため非常に便利です。

また、ELBはスケールしIPアドレスが変わることがよくありますが、都度Route53の設定を変更する必要がないので助かります。

Route53ドメイン名と紐づくホスト名の設定だけ見ると、まるでCNAMEリソースレコードのように見えますが、A/AAAAリソースレコードでこの仕組みを実現しているのが面白いです。

スタブリゾルバー

RFC1034ではスタブリゾルバーが必要とするのはネームサーバのリストであると書かれています。

All that the remaining stub needs is a list of name server addresses that will perform the recursive requests.

linuxmacでは /etc/resolv.confにネームサーバのリストが記載されているので、スタブリゾルバーはおそらくこのファイルを参照しにいくことが推測されます。

試しに、自分のMac/etc/resolv.confを見てみました。

$ cat /etc/resolv.conf
# This file is automatically generated.
#
search flets-east.jp iptvf.jp
nameserver 2404:1a8:7f01:b::3
nameserver 2404:1a8:7f01:a::3
nameserver 192.168.0.1

nameserverの上2つはNTT東日本DNSサーバのアドレスです。西日本用のアドレスもあります。参考

192.168.0.1はデフォルトゲートウェイで、ルータやモデムがadmin画面にログインするために利用されます。参考

ネットワークの設定を切ると、自動的に/etc/resolv.confの書き込みも消されます。

$ cat /etc/resolv.conf
# This file is automatically generated.
#

Goのスタブリゾルバーの実装

Goでスタブリゾルバーの設定を定義している構造体です。

Go実行時にresolvConf変数が作成され、 lookupメソッドが実行された際に/etc/resolv.confを読み込みサーバ情報などを取得しているようです。

// A resolverConfig represents a DNS stub resolver configuration.
type resolverConfig struct {
    initOnce sync.Once // guards init of resolverConfig

    // ch is used as a semaphore that only allows one lookup at a
    // time to recheck resolv.conf.
    ch          chan struct{} // guards lastChecked and modTime
    lastChecked time.Time     // last time resolv.conf was checked

    mu        sync.RWMutex // protects dnsConfig
    dnsConfig *dnsConfig   // parsed resolv.conf structure used in lookups
}

var resolvConf resolverConfig

コード

10月にfacebookで起こった障害

2021/10/05にfacebookのサービス(InstagramやWhatsApp)のDNS名を解決出来なくなっていました。(障害の詳細レポート)

定期メンテナンス時に発行されたコマンドに誤りがあったことによって、Facebook内部のbackbone(internetからサーバーへの通信の中継点)からサーバーへの通信が切れてしまったようです。

その通信の断絶を検知し、Facebookが所有するDNSサーバがBGPによってFacebookへのルーティングをストップさせたことで、 インターネットからFacebookのサービスのドメインの名前解決ができなくなったようです。

障害の調査に利用する内部ツール自体も利用できなくなってしまい、障害解決に時間がかかったしまったみたいです。

CloudFlareの記事で、外部サービス(CloudFlare)かの障害状況レポートが報告されており、何が起こったかを知ることができるので一読をおすすめします。

DNS関連の障害の時は常ですがユーザやアプリケーションからリトライ通信が多発していたようですが、今回のケースではCloudFlareのDNSサーバに通常時の30倍のクエリがあったようで、DNSサーバを自前運用することの大変さを感じました。

感想

色々と調べていくうちにまとまりがない記事になってしまいました、、、本を読み色々と調べていけば行くほど、DNSの奥深さを感じていきます。

Facebookの障害からもDNSが障害の起因になりやすく、その影響範囲も甚大であることがわかります。

DNSを運用していくことの責任の重大さをひしひしと感じます。AWSがRoute53のSLAを100%に定めていることから、ベンダーも同じように認識していそうです。(Route53 SLA)

今後、新たに学んだことを追記していきたいと思います。