本日の記事は、IIJでDNSサービスを担当している山口 崇徳が執筆しています。

本記事に関連した講演が、本日13:45~開催されるIIJ Technical WEEK 2016で行われます。(該当のセッションは16:45~予定の「DNSにまつわるセキュリティのあれこれ」です)ストリーミング中継も行いますので、是非ご覧ください。

このごろ DNS ってこうげきをうけることがおおいんだって。

DNS は「どめいんなまえしすてむ」のことで、ドメインのなまえをきくと IP アドレスをおしえてくれたりするしくみだよ。わるいひとたちが DNS をいじめてつかえないようにしちゃうと、インターネットであそべなくなっちゃう。

だったら、それにまけないつよい DNS をつくればいいよね。

どんな攻撃が来るのか

……すいません、読みにくいですね。漢字使います。なお、漢字で書いたところで中身は「ぼくのかんがえたさいきょう」に違いありません。

DNS に対する攻撃は大きくわけると、2つ。DoS と DDoS です。DoS は denial of service の略で、主にシステムの脆弱性を突いてサービスを停止させるもの。DDoS は distributed DoS で、多数の端末から分散してネットワークやサーバの処理限界を越える大量トラフィックを送りつけることで過負荷状態にしてサービスを停止させるもの。

つい先日も国内海外で大規模な DDoS 事件があり、多くのサイトが影響を受けたのはまだ記憶に新しいところです。DDoS 攻撃の規模は年々拡大しており、また、現状では DNS サーバは攻撃のターゲットとして選ばれる傾向が強いことから対策は急務です。

多くの場合、攻撃者の狙いは Web サイトの閲覧不能です。なので直接 Web サイトを攻撃してもいいのですが、手段はそれにかぎりません。Web サイトを閲覧するにはまずそのサイトの IP アドレスを知る必要があり、ならば、その IP アドレスを知るための仕組み = DNS を機能不全に陥れることでも狙いを達することができます。まず Web サイトを直接攻撃してみて、これが落ちないようだと攻撃対象を DNS に切り替える、という流れが多いようです。

DNS サーバは大きく権威サーバ(コンテンツサーバとも。大元の情報を管理するサーバ)と、参照サーバ(いわゆるキャッシュサーバ。権威サーバに情報を問い合わせるサーバ)にわけられますが、攻撃の対象にされるのは主にドメインの情報を握っている権威サーバの方になります。今回検討する「さいきょう」も権威サーバについてです。

分散して守る

教科書どおりであれば、権威 DNS サーバはプライマリ/セカンダリ構成にして複数のサーバで運用されます。が、プライマリ1台にセカンダリ数台といった昔ながらの構成では、大規模化している昨今の DDoS にはまったく対抗できません。可用性を高めるにはどうすればいいのでしょうか。

Anycast という技術があります。通常、IP アドレスは機器ごとに固有のものを付与しますが(Unicast)、そうではなく「同じ IP アドレスを複数のサーバで共有する」技術です。同じ IP アドレスを持った「分身」ホストを世界中の各地に設置し、よしなにルーティングすることにより、たとえばラダトームからのアクセスにはラダトーム城に設置した分身サーバにルーティングされ、リムルダールからのアクセスにはリムルダールの街に設置した分身サーバにルーティングされる、という動作になります。

エニーキャストのせつめい
エニーキャストのせつめい

アクセスが複数のノードに分散されることから負荷の軽減になり、また多くの場合クライアントからのアクセスは複数ある拠点のうちもっとも近いノードに誘導されることから、応答時間の短縮に寄与します。

しかし、「さいきょうの DNS」という観点では、障害を局所化できるという点が重要になります。昨今 DNS は DDoS 攻撃のターゲットとして大人気ですが、distributed (= 分散) DoS といえど、攻撃者が世界中に均等に分散していることは稀で、メルキドからだったり、ドムドーラからだったり、攻撃元の地域は大きく偏るのがほとんどです。攻撃対象の IP アドレスは攻撃者が自由に決められますが、その IP アドレスが Anycast されていた場合にどのノードにルーティングされるかを攻撃者が決めることはできません(送信元アドレスを偽装したとしても不可能です)。そのため、Anycast 構成では攻撃元の地域が偏れば攻撃対象となるノードも大きく偏ることになり、結果として特定のノードが攻撃を吸い込んで他ノードに被害を波及させないという効果が期待できます。

ラダトーム城と竜王の城は海を挟んで目と鼻の先で、地理的には非常に近い位置関係にありますが、いざとなれば竜王の城からの攻撃が海底ケーブルを通ってラダトーム城を直撃しないよう、ドムドーラ方面に経路広報を向けかえるという操作も可能です。特定拠点に意図的に攻撃を集中させることにより、結果としてドムドーラに設置した Anycast ノードは廃墟になるかもしれませんが、その影響があるのは竜王の城やドムドーラ周辺地域からアクセスしてる人だけで、アレフガルドのその他地域からのアクセスを救うことができます。

エニーキャストのせつめい2
エニーキャストのせつめい2

もっとも、そうはいっても先日 DDoS 攻撃を受けて世界的に障害になった Dyn も Anycast を採用してたんですよね。DDoS に加担する bot の数が多くなると、地域的な偏りがあったとしてもやはり無視できないトラフィックが押し寄せてきます。それでも、日本はまだ影響が軽微で済んだ方で、北米、ヨーロッパの状況はもっと酷かったようです。日本での障害規模があの程度で済んでいたのはやはり Anycast 構成だったおかげと言えるでしょう。

なお、実際に Anycast 化するとなると、広く世界各地にノードを構築しないと意味がないので、単純にコストがかかります。ノードが増える分だけ手間も増えます。

緩和して守る

Anycast では攻撃が局所化され、一部の障害が全体に波及しないようにはできますが、逆に言えば、一部のノードだけが集中攻撃に晒されるということでもあります。もしそこが陥落すると、そのノードがカバーしている地域全体からの名前解決ができなくなってしまいます。攻撃元には地域的な偏りがあるとはいえ、その地域には攻撃に加担していないクライアントももちろんたくさん存在しているわけで、それらも巻き添えになって名前解決できなくなるようでは「さいきょう」を名乗れません。

じゃあどうすればいいのか。どんなに大量のトラフィックが来ても受け止められるさいきょうのサーバがあればいいんです。はい、単純な答ですね。

といっても、その単純な答を簡単に実現できるなら誰も DDoS で困ったりしません。具体的にはまず、巨大な攻撃トラフィックがやってきても埋まることのない大きな帯域のネットワークが必要です。しかしそのトラフィックをすべてサーバに向けるのは無駄です。DNS の応答を必要としない攻撃者に律儀に応答を返してもしかたないですし、UDP を使うという DNS の特徴から攻撃元の IP アドレスは詐称されてる可能性が高いですし、そもそも攻撃パケットが DNS の問い合わせではないことも多いでしょう。こういうパケットまで DNS サーバに到達させてしまうと、外部ネットワークとの接続点だけでなく、内部ネットワークでも輻輳が発生してしまうおそれがあります。

そこで、攻撃の可能性の高い異常トラフィックは DNS サーバに到達する前に破棄し、正当な DNS 問い合わせのみを通すようにする仕組みが必要になってきます。

ぼうぎょ
ぼうぎょ

こういったことは一般的にはファイアウォールが得意とする分野ですが、一般的なファイアウォールとは挙動が若干異なります。ルールにもとづいてパケットを単純に許可/拒否するのではなく、通常は許可するようなパケット(例: DNS クエリ)であっても、過去の通信パターンの学習結果から予測される値を大きくはずれたパターンを検出した場合は異常とみなすなど、動的に防御モードを変化させるような挙動が求められます。

使いわけて守る

DNS サーバに使われるソフトウェアとしては、BIND のシェアが圧倒的に大きいようです。信頼できそうな統計が見つからないのですが、一説によると8割以上のシェアを占めてるそうな。

しかしみんな使っているから安心かというとそうでもなく、BIND は外部からの攻撃でサービス停止に陥るような脆弱性が年に数件発見されています。とくに、なぜか毎年のように7月になると BIND の脆弱性が発見されるので、DNS 関係者には夏の BIND 脆弱性祭を存分に楽しむため、7月はスケジュールを空けて待ちかまえる人も多いようです。今年の7月は影響範囲の極めて小さいもので拍子抜けしたところに、9月末になってヤバい脆弱性をブチこんでくるフェイントを決めてくるなど、いつも運用担当者を飽きさせることがありません(だいぶ感覚が麻痺してる)。

常に最新の情報を追いかけて、サービスに影響のある脆弱性にはすべて対応しているようにはしていますが、未知の脆弱性を突かれることがないともかぎりません。仮に BIND がめったに脆弱性が見つからないソフトウェアだったとしても、あるいは BIND を捨てて別の実装に完全に乗り換えたとしても、脆弱性がまったく存在しないと保証することは誰にもできず、未知の脆弱性を狙われる危険から逃れることはできません。

ではどうすればいいのか。ダイバーシティ(多様性)、これが答です。単一のソフトウェアに頼るのではなく、複数のソフトウェアを併用します。特定の実装の未知の脆弱性を狙うような攻撃を受けたとしても、複数の実装を使いわけていれば影響を受けるのは一部のサーバだけになり、残りのサーバで DNS サービスを継続できます。

ただ、これを実際にやると、サービス全停止の可能性は低くなりますが、一部停止になる可能性はむしろ大きくなります。しかし、DNS サーバが応答しなければクライアントは別のサーバに対して問い合わせしなおすので、一部でも生きていれば多少の応答性の劣化程度で済み、致命的な障害にはなりません。また運用視点では、複数のソフトウェアを保守しなければならなくなり、手間が単純に2倍になります。

つくってみた

「ぼくのかんがえたさいきょうの○○」ってのはだいたい小学生並の発想から生まれた荒唐無稽で無茶苦茶なものですが、上で挙げたようなものはすべて既存の技術で実現可能なことではあります。必要なコストと手間はハンパじゃないですが、そのハードルを乗り越えて実現できれば攻撃にはとても強くなります。

実現できるといいよねー。

……なんてね。

「ぼくのかんがえたさいきょうの DNS」は妄想ではなく、「これから作るぞ」という決意表明でもなく、IIJ では実現してすでに稼働中です。DNS アウトソースサービス/セカンダリサービスを契約するだけで、ご利用のドメインが「さいきょう」になります。

Anycast してます。国内、海外の複数拠点に分散配置。平常時は応答時間の短縮に寄与し、攻撃を受けているときには被害が他地域に及ばないように局所化します。海外の大手 DNS ホスティング事業者では Anycast を導入してるところは多くなってきましたが、国内で Anycast 構成を採用している事業者はまだまだ少ないのが現状です。

Anycast しないサーバもあります。正常な問い合わせにはふつうに応答を返しつつ、DDoS 攻撃と思われる異常トラフィックは DNS サーバの手前でブロックしてネットワークへの流入を食い止めることで、飽和攻撃への耐性を高めています。ちなみに DNS 以外にも使える DDoS プロテクションサービスもあります。

もちろん、Anycast ノードも非 Anycast ノードも、どちらも各ノード内は完全冗長化構成になっています。BIND の脆弱性にはいつも泣かされてますが、冗長化されているので入れ替え作業をおこなうときでも一瞬の断もなくサービスを継続できます。もちろんサーバだけでなくルータやスイッチなどのネットワーク機器も冗長化されてします。
そして多様性の確保。圧倒的シェアを誇るけどセキュリティ上の不安が拭えない BIND とともに、パフォーマンスに優れ致命的な脆弱性の少ない NSD も使ってます。複数の実装を併用することで、特定の実装の脆弱性を狙われたとしてもサービス全停止になる可能性を下げています。

ちなみに NSD を採用するにあたり、いくつか機能を追加するパッチを IIJ で作成して開発元に取り込んでもらってますが、どちらかというと「こんな機能追加したからよかったらみんな使ってみてね」というオープンソースに対する崇高な貢献の気持ちよりも、「勝手に追加した機能だけど、今後もずっとメンテするのダルいんで後はよろしく」という運用コスト削減の方が理由としては大きかったりします。

まとめ

特定の障害や攻撃によってサービスが全断するのではなく、一部のサーバにしか影響しないように、複数の手法を組み合わせてるよ。

  • Anycast して地域分散しているノードと、Anycast してないけど極限まで強いサーバのノードを組み合わせてるよ
  • 複数の DNS 実装を採用して特定の脆弱性で全サーバが影響を受けないようにしてるよ

なお、非常に堅牢なシステムではありますが、とはいえやはり限度というものはあります。しかし、DDoS と判断する閾値やどの程度の攻撃まで耐えられるかなどといった具体的な値についてはここでは触れません。個別にお問い合わせいただくこともありますが、それに対しても回答していません。攻撃を計画している者にその回答が流出した場合に、どれほどのトラフィックがあれば落とせるのかという目安を与えることになってしまうのを避けるためですのでご了承ください。

以上、IIJ の DNS サービスは強いよ、というお話でした。

攻撃に強いけど、だからといって攻撃するなよ。上島メソッドじゃないからな、絶対に攻撃するなよ。Mirai とかマジやめて。

※説明をわかりやすくするためにドラゴンクエスト(C)スクウェア・エニックスの地名を引用させていただいております。