社内DNSでCNAME使うときはTTLに気をつける
「システムに接続できないけど、たまに繋がる」ということによく遭遇してしまいますよね。
今回は、Windowsのマルチドメインな環境を見ていて、こういったことが起こるのでは?という思いつきが発端の記事です。
異なるドメインのシステムへの接続がうまくいかない、よくよく調べてみるとcnameとTTLそして環境内で不通の箇所があったことが原因だったという話です。
Contents
環境
まず環境として3ドメインあります。昔からあるAドメイン、とあるシステムのために作成されたCドメイン、今回新たな拠点向けに追加されたBドメインという感じ。
DNSサーバはすべてWindows ServerのDNSサーバで、AドメインのDNS0とDNS1はAD。DNS0が一番昔からあるDNSサーバで、ここがルート的な動きをしている。DNS1も内容的にはDNS0と同じだが、ミスによりDNS3へのリーチャビリティがない。
BドメインのDNSサーバはインターネット等使うために昔からあるAドメインのDNSサーバをデフォルトフォワーダーとして設定。具体的には最近構築されたDNS1に設定。AドメインとBドメインはADの信頼関係を構築しており、その都合でDNS2からAドメインはDNS0と1向けに条件付きフォワーダも設定されている。
Cドメインのシステムsys.CをAドメインから使いたかったが、ドメイン名がCになるのがちょっと気になったのでsys.Aというcnameを使うことにしていた。
さて、今回画像左のPC(Bドメイン)からもCドメインのシステムを使いたいと思っている。このとき問題が発生しました。どういう問題が起きたでしょうか?
名前解決のフロー
実際のフローを見るとわかりやすいかと思い、図にしました。
- PCのDNSサーバとして設定されているDNS2にsys.Aを再帰問い合わせ
- DNS2は条件付きフォワーダ先のDNS0に再帰問い合わせ
- DNS0は条件付きフォワーダ先のDNS3に再帰問い合わせ
- あとはその戻り
問題が無いときは↑のフローで名前解決ができます。ただ、このケースでは60秒後に名前解決できなくなります。
キャッシュ
実はキャッシュが悪さをします。30秒後と60秒後のキャッシュは以下のようになります。
30秒後の段階ではDNS2にsys.Aもsys.Cもキャッシュが存在しているので問題はないのですが、sys.AのTTLが60に設定してあるため、60秒後にはsys.Aのキャッシュしか存在しなくなります。
こうなったらどうなるか見てみましょう。
- PCからsys.AのIPをDNS2に再帰問い合わせ
- DNS2はsys.Aがsys.Cのcnameであることはわかるのですが、そのIPがわからないのでデフォルトフォワーダーのDNS1にsys.CのIPを再帰問い合わせ
- DNS1はドメインCは条件付きフォワーダでDNS3に聞くことになっているのでDNS3に再帰問い合わせ
- しかし、NWが不通のため応答がない
- DNS2からDNS1への問い合わせもタイムアウトとなる
- PCにはsys.Aはsys.Cのcnameという応答だけ帰ってくる
ということで60秒後に名前解決ができなくなります。その後3540秒後にsys.Aのキャッシュも消えれば問題なく名前解決できますが、またその60秒後に名前解決できなくなり、3540秒後まで名前解決できなくなる..というループが続き、「システムに接続できないけど、たまに繋がる」といった事象が発生します。
原因
直接の原因はDNS1からDNS3へのリーチャビリティがないことです。ここはちゃんとつなげておきましょうですね。
今回のポイントは、cnameのTTLがその先のAレコードと異なってしまっている、ですね。cnameのキャッシュだけあってもまた問い合わせることになり、キャッシュの意味そこまでないのでTTLは合わせておいたほうが良さそうです。
それ以外にも要因となった事柄には次のようなものがあります。このあたりは以外と忘れがちなのでこのような事件をきっかけにおさらいしておくと良いかもしれません。
- Windows ServerのDNSは条件付きフォワーダ先でタイムアウトになってもデフォルトフォワーダーに問い合わせしない(フェイルオーバーしない)
- DNSサーバはcnameに対応するキャッシュがなくなった場合、cname先に自らが再帰問い合わせする
そのほかの解決策としては以下。
- DNS2のデフォルトのフォワーダをDNS0に変更する
- DNS2にCドメインへの条件付きフォワーダーを追加して、DNS3へNW接続
- sys.CのAレコードをDNS2に書く
キャッシュをオフにするのは性能面考えると無しです。
最後に
今回はマルチドメインなDNS環境で名前解決できなくなってしまった話でした。
複数DNSサーバを使っている環境では、すでに動いているところにデフォルトフォワーダー向けておけばいいか、となりがちですがそこでは動いていてもフォワーダーとして使うと動かないということもあるので対策は難しいですが注意が必要です。
特にcname使うと条件付きフォワーダなどによってルートが変わったりして名前解決できなくなることもあるので、せめて自分が管理しているDNSではcnameを書くときはその先のレコードのTTLと合わせておくと良さそうです。