CVE-2015-7547をDNSで何とかする方法を考えてみる

投稿者: | 2016年2月19日

編集長の佐藤(@akihirosato1975)です。

一昨日辺りから話題の例のglibcの脆弱性(CVE-2015-7547)ですが、現実には既存システムの動作検証とかの手間やらユーザへの告知やらが絡んで、なかなかglibcのバージョンアップに踏み切れない環境も多いかと思います。
とりあえず「DNSから2048bytes以上のquery responseを受け取らなければ脆弱性は表面化しない」というのがあるので、社内のDNSサーバに「response sizeを2048bytes以下に制限する」設定を仕込んでなんとか週末を乗り切って時間を稼ごうという方々も多いと思いますが、いざこれを実行しようとすると結構難儀だったりします。
個人的にそのあたりの手順をいくつか調べてみたので、せっかくなのでまとめてみました。
#あくまで個人レベルで簡単に試してみた程度の話なので、弊社として動作を保証するものではありません。最終的な動作確認及び責任は実行した各人にてお願いします。
#あと以下の設定変更はそれなりに副作用も伴います。特にゾーン転送とかDNSSECとか、response sizeが大きくなりがちな機能を使っている方はご注意ください。

PowerDNSの場合

PowerDNSの場合は話が簡単で、既に開発元の公式ブログで対策スクリプトが公開されてます。
DNSサーバの適当なところにこのスクリプトを保存した上で、PowerDNS Recursor(pdns-recursor)のconfファイルで、「lua-dns-script」にスクリプトファイルを指定して再起動、というのが一番手軽でしょう。

Unboundの場合

Unboundでは、あまり好ましいやり方ではないですが、一応こんな感じでresponse sizeを制限できるっぽいです。

  1. unbound.confの「edns-buffer-size」と「max-udp-size」を2048以下に設定する。
  2. 同じく「do-tcp」を「no」に設定して、TCP fallbackを無効にする。

ちなみに「max-udp-size」がUnbound 1.4.21以降でないと使えないので、古いバージョンの方はバージョンアップが必要です。

本当は「msg-buffer-size」を2048とかに設定できるとよかったんですが、msg-buffer-sizeは4096以上を設定しないと起動時エラーになるため、その手は使えませんでした。ただTCP fallbackを無効にできない場合でも、巨大なTCP responseを防ぐという意味でmsg-buffer-sizeに小さい値を設定するというのは、今回の件への対処ということに限って言えば無駄ではないと思います。

その他の環境の場合

既にいろんなところで貼られてますが、glibcの脆弱性対策(取り急ぎiptables/firewalldで叩き落とす!)for CVE-2015-7547とかにあるように、tcp/udpのレイヤでresponseを叩き落とす方法を考えたほうが良さそうです。
少なくともBINDの場合、UDPサイズは「max-udp-size」等で制限できても、TCP fallbackを防ぐ手段がBIND単体だとなさそうなので。firewallレベルでPort 53はUDPのみ許可するとか、他の手段と組み合わせないと厳しそうです。