digでDNS参照のタイムアウトへの対応
自宅用にzabbixを立ち上げたので、dynamic DNSが更新できているかのチェックを入れてみました。
自宅が外部からどのIPに見えているかを外部サービスを使って取得した値と、dnsを参照した値と比較する、という作りにしました。以下のパラメータでDNSからIPを参照しています(example.orgのところはダミーです)。
UserParameter=net.ipv4.ext.dns,dig example.org | grep ^example | awk '{print $5;}'
が、不一致が結構出てアラートがそればかりになってしまいました。
不一致の原因
不一致の原因を調べると、digによるDNSに登録されているIPアドレスの取得が失敗していたことが分かりました。感覚的なものですが20~30%は失敗していました。
digを実行して取得できるはずの値が取得できなかった、という記憶がなく意識していなかったのですが、タイムアウトなどが結構厳しく失敗は起こりうるもののようです。
DNSサーバの指定
OSのdnsサーバーとしては自宅ルーターのアドレスと、googleの8.8.8.8を指定していたのですが、8.8.8.8を参照したときにエラーとなったので、参照するDNSサーバーを明示するようdig @自宅ルーターのIP FQDN
に修正しました。
DNSはUDPを使用するため、ある程度遠い8.8.8.8ではパケットの損失が起こり得る、と、深くは考えませんでした。この対応でエラーは減ったような気もしましたが、結局再発しました。
タイムアウト時間の指定
ここでようやく原因を調べたところ、digではDNSクエリのタイムアウトが5秒(The default timeout is 5 seconds.)なので、何かで詰まっているとエラーになってしまうようです。
Zabbixエージェントからの実行であるため、多少応答に時間がかかっても問題はないと判断し、 dig +time=30 @192.168.100.1 example.org
のように変更したところ取得の失敗がなくなり、警告が出なくなりました。
おそらく、タイムアウトの指定だけでも大丈夫だと思いますが、自宅ルーターへのDNSサーバー指定も残しています。ただ、googleなど外部のDNSを参照したほうが目的からすると意味がありそうな気もします。
感想
今までdigを叩いて取得できるはずのアドレス取得に失敗した記憶がなかったのに結構な頻度で失敗することが、ちょっと意外でした。
原因はきちんと調べたほうが結局早く解決することに繋がる、という教訓にもなりました。