初めに
PowerDNS Authoritative Server(以後PowerDNS)は、3.4.10がリリースされました。
3.4.9から3.4.10のChangeLogに、
commit 881b5b0: Reject qnames with wirelength > 255, chopOff() handle dot inside labels
があり、これでPowerDNS Security Advisory 2016-01(CVE-2016-5426およびCVE-2016-5427)の対応をしています。ここでは、CVE-2016-5426の影響度について考察します。
注意事項
CVE-2016-5426についてPowerDNS BVおよび発見者から情報を得てはいませんので、ここに記載されている内容は、公開されている情報から推測したものです。
CVE-2016-5426について
CVE-2016-5426の概要は、
- 細工したDNSクエリを送信することで、バックエンドのCPU使用率が上昇する。
というものです。
PowerDNSはゾーンの情報を、データベースやディレクトリサーバなどのバックエンドに持たせています。PowerDNSは受信したクエリをもとにバックエンドに問い合わせ、その応答を受信してDNSレスポンスを生成し、それを返します。ここで注意しなければならないのは、ひとつのDNSクエリに対して、バックエンドへの複数の問い合わせが発生することです。
実験
環境
- PowerDNS サーバ(pdns-front)
- 論理CPU x 4
- メモリ4GB
- OS CentOS 6.8 64bit
- CPUごとの使用率に偏りがでるため、以下の設定を追加
echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
- PowerDNS 3.4.9
- pdns.confのreceiver-threadとreceiver-threadsを20に変更。デフォルト値では、バックエンドの負荷があまり上昇しないため
-
net-snmp CPU使用率などの取得のためsnmpdを使用
- バックエンドサーバ(pdns-back)
論理CPU x 4
メモリ4GB
-
OS CentOS 6.8 64bit
- CPUごとの使用率に偏りがでるため、以下の設定を追加
echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
- MySQL 5.1.73(mysql-server-5.1.73-7.el6.x86_64)
- my.cnfは未修正
- net-snmp CPU使用率などの取得のためsnmpdを使用
方法
以下のようなDNSクエリをPowerDNSへ送信し、pdns-frontとpdns-backのCPU使用率をSNMPを利用して計測しました。
- 20qpsまたは50qpsのクエリをpdns-front送信
- QNAMEはランダムに生成
- QNAMEの長さを250, 1000を変えて、それぞれの場合を計測
- QNAMEはバックエンドのクエリが多くなるように工夫
- クエリに対するレスポンスを待たない。QNAMEの長さが255を超えると、レスポンスのDNSメッセージを作成するときに、例外(C++)が発生してレスポンスがなくなるため
結果
pdns-frontとpdns-backのCPU使用率は以下のようになりました。グラフの山は左から
- QNAMEを250として20qpsのクエリを送信
- QNAMEを1000として20qpsのクエリを送信
- QNAMEを250として50qpsのクエリを送信
- QNAMEを1000として50qpsのクエリを送信
ときのものです。QNAMEの長さが1000の場合は、バックエンドサーバのCPUおよびPowerDNSサーバのCPU使用率も高くなりました。
pdns-front
pdns-back
考察
バックエンドサーバのCPU使用率が高くなったのは、PowerDNSから非常に多くのクエリがMySQLへ送信されたためです。QNAMEの長さが1000程度の場合、ひとつのDNSクエリに対して、1000以上のクエリをPowerDNSからバックエンドへ送信させることが可能です。このように多くのクエリが送信される理由については、MySQLのクエリログを参照してみてください。
50qps程度のクエリは一台のPCでも容易に生成することが可能ですので、CVE-2016-5426を利用することにより、PowerDNSのバックエンドサーバを過負荷にすることができます。PowerDNSサーバを利用したサービスをDDoSで落とすことは容易にできてしまうということです。
上記のCPU使用率の増加は、QNAMEの長さを短くすることで抑制することができます。PowerDNS 3.4.10では255以下に制限されているので、CPU使用率は大きくなりません。
まとめ
PowerDNS Authoritative Server 3.4.9以下を利用している場合は、少ないクエリ数で容易にサービスを止められてしまいますので、早急に3.4.10にしましょう。
おまけ
CVE-2015-1868, CVE-2015-5470, CVE-2015-5230, CVE-2016-5426と続いたドメイン名関係の脆弱性も、これで終わってくれるといいですね。