Vyatta のDNS Forwarding にハマった話

network-graph

DNS Forwarding

Vyatta には DNS Forwarging の機能があります。 これを使うと、 Vyatta に対して DNS リクエストを行うと、外部ネットワークの DNS を引いて、その結果を転送してくれます。

たとえば、上図のネットワークでは akari で DNS が動いているとして、 Vyatta でルーティングしている 192.168.2.0/24 で DNS Forwarding をon にすると、 imac から 192.168.2.1 に DNS リクエストをすると 192.168.1.10 に同じリクエストをした結果が返ってきます。

実際には、 Forwarding とは言ってもデフォルトでキャッシングが有効になっているので、一旦 Vyatta のキャッシュにレスポンスが貯められて、そのキャッシュから imac に対してレスポンスが返るようです(cash-size を0にすれば、言葉通りそのまま転送されてきます)。

127.0.1.1 が返ってくる

DNS Forwarding をon にした状態で、 vyatta 自身のレコードを imac から引くと、なんと驚いたことに127.0.1.1 が返ってきます。 もちろん、akari のZone ファイルには vyatta が 192.168.3.1 で登録されています。 別のネットワークでレコードを引くと、ちゃんとこの値が返ってきます。

この問題には悩まされました。 vyatta にログインして nslookup vyatta をすると 127.0.1.1 が返ってくるので、どうやらVyatta 内部のレコードが DNS Forwarding よりも優先されて返されているようです。

問題はタイミングだ

色々調べてみると、 /etc/hosts にvyatta の値として 127.0.1.1 が設定されています。 どうやら、この値が返されているようです。 そこで、この行を削除してみたのですが、結果に変わりはありませんでした。

ここが原因では無いと判断して、 /etc/hosts の値をそのままに、Vyatta の DNS Forwarding の設定値をいじって commit して named が再起動してレコードを引いてみたら、今度はちゃんと期待する akari からのレスポンスが返ってきました。

この設定の変更が原因であると疑って、設定をもとに戻せば再現するかと思って設定を戻して commit してみたところ、それでも期待する akari からのレスポンスが返ってきました。

この結果から導かれた仮説は、 "named が起動するタイミングで /etc/hosts が読まれ、この結果が転送先の DNS のレコードよりも優先される" というものです。 そこで、 /etc/hosts を元に戻して、設定の変更をせずに named をリスタートした結果、再度 127.0.1.1 が返ってくるようになったので、この仮説が実証されました。

リセットされる /etc/hosts

通常運用ではルーターを再起動するような機会は滅多にないと思うのですが、その必要が生じたとします。 すると、 Vyatta は system host-name の値を見て /etc/hosts をリセットしてきます。 このリセットのタイミングは named の起動よりも先ですし、後だったとしても2回目の再起動で結局変更は元に戻ってしまいます。

解決策として以下の方法が考えられます

  1. /etc/hosts を書き換えるシェルスクリプトを書いて、 Vyatta の機能を使って起動時に実行されるように設定する
  2. Vyatta の system host-name に適当な値を設定して、 akari のレコードと被らないようにする
  3. DNS Forwarding を使わない

私が取った方法は3ですw最も楽な方法を取りました。 akari の named の設定とファイアウォールの設定を変えて、 192.168.2.0/24 からのクエリを許可したうえで、 DHCP を使ってネームサーバーとして 192.168.1.10 を配りました。