DNSamp対策

2013年9月1日 (日) 09:48時点におけるTakahashi (トーク | 投稿記録)による版 (実はそれだけではすまない)

目次

何をやられるのか?

DNSampはオープンリゾルバを狙ったDOS攻撃のひとつです。DNSサーバに対して別名ドメインのクエリを行い、その時に得られる応答が「なるべく長いもの」を要求するDOSです。

DNS Query -----> [DNS Server]

と、いうのが普通のDNSサーバの動作なのですが、オープンリゾルバは自分のサイトに関係ない情報にも応答してしまうDNSサーバです。
例えばVoIP-info.jpの場合には、www.voip-info.jpとかvoip-info.jpのMXレコードには応答するべきですが、www.google.comのような「よその」ドメインに対するクエリがなされた場合には応答する必要はありません。応答してしまうものをオープンリゾルバと呼びます。
ですが、DNSサーバは何も外から引かれるだけでなく内側からも引かれるわけで、その場合には内側からは外のドメインが引けるけれども、外からは他のドメインが引けてはいけないという条件が必要になります。

          外←|→内
DNS Query -----> [DNS Server] <----- DNS Query
×www.google.com->         <-○www.google.com

これはDNSサーバの設定のリカーシブ機能のことで、通常は上記のような挙動をするようにリカーシブは自ドメイン/ネットワーク内だけに許可を与えます。
普通はこの対策をしておけばリカーシブされないので、DNSamp攻撃は防ぐことが出来るように思えます

実はやっかいだった対策

ここ(voip-info.jp)を含む、高橋のネットワークではいくつかのDNSサーバが動いていますが、いずれもオープンリゾルバにはなっていません。このためDNSamp攻撃に対する対策はできてたはずでした。
ところが2013年8月に入ってから攻撃が激化し耐えられなくなりました。
理由はこうです

The Net -----> [Top Router] -----> [DNS Server]
     DNS Query -------------->

単純にいうとネットワークはこういう構造になっており、トップ・ルータの下にグローバルなネットワークがあります。ここにはグローバルIPに出ているサーバ類がいます。
迂闊だったのはこのトップルータの性能でした。DNSのクエリはご承知の通り、UDPのショートパケットです。このため、一度に大量のクエリが投げつけられるとDNSampによる被害そのものは出ないものの、リクエストが大量すぎてルータのCPUが一杯一杯になってしまい、他のトラフィックが通れないという状況になってしまいました。
さらに悪いことに、特定のサーバ宛てのクエリを遮断しようとフィルタをかけたり、またそのログを取得しようとするとフィルタの「弾き返し性能」によりルータの負荷は上がり、ログのためのUDPでトラフィックはますます上がるという悪循環に陥ります。
そんなわけで、トップルータをより高性能なものに交換するという措置を取りました。

実はそれだけではすまない

みなさんご承知の通り、UDPのショートパケットのスイッチング性能は高いルータでもそれほど高くなかったりというやっかいなものです。VoIPでも頭を悩ませるところのひとつですからね。
オープンリゾルバに対する問題は、サーバとルータに気をつけてれば良いはずだったのですが、実はちょっとした問題があり、サーバを運用していない人にも影響する可能性があります。
ヤマハからも注意喚起が出ている(オープンリゾルバー(Open Resolver)に対する注意喚起について)のですが、ルータそのものがDNSサーバ機能を持っているものに関しては、この攻撃を受けうる可能性がとても高いことになります。
例えば次のような例でも対象になり得るかもしれません。

           PPPoe<-|NAT|-> Local IP
The Net -----> [Router] ----- Local Net

ごく当たり前のPPPoEなどによる接続かつ、NATを使用している場合、ローカル側ではDHCPを使ってIPアドレス、ゲートウェイ、DNSサーバを取得してきますが、この場合にはルータそれ自体がDNSサーバの役目をしています。
では、次のような場合の挙動は?

           PPPoe<-|NAT|-> Local IP
The Net -----> [Router] ----- Local Net
 DNS Query ---->

ルータのIPアドレスめがけてDNSクエリが行われた場合、このルータはどのような挙動をするのでしょうか?それはわかりません。ルータの実装よりけりだからです。もしこれに応答するルータがあって、なおかつリカーシブに応答してしまうと、ルータそのものがDNSamp用の踏み台とされかねません。
一般的なルータで入力側にフィルタ機能がある場合には「外」からのDNSクエリに対してはブロックするという作戦を取ることができます。

           PPPoe<-|NAT|-> Local IP
The Net -----> [Router] ----- Local Net
DNS Query(53)->×
           ○<-DNS Query

もちろん内からは問いあわせなければいけないので、内から外へのクエリは通します。これで少しは安心なのですが、大量のクエリ、すなわちUDPのショートパケットを投げつけられると、家庭用のルータではちょっと性能が心配になります

追記:『普通の』アクセスルータでも入力(WAN)側のフィルタが適切でないと外からのDNSクエリに応答するものがありました。ということは単なるアクセス回線しか持っていなくてもDNSampに荷担する可能性があります。

サーバを運用している場合の対策(ヤマハルータを使った対策)

サーバを運用している場合にはオープンリゾルバになっていなければ、外から問いあわせされてもRefusedで返るので特に問題ない「気」はします。ですが、当然ながら猛烈なトラフィックを食らうと他のサービスに影響する可能性があります。でまあ、何といってもやっかいなのが、そこそこ性能のあるルータがないと戦えないという点なのですが・・・

以下の例ではヤマハを使った対策を示します。設定例はFWX120のものですが、RTX系でも使えると思います。

QoSをかけてしまう

DNSクエリが多大なトラフィックになってしまうのであれば、QoSをかけて低減すれば他のサービスに影響を与えにくくなります。こんな感じ


The Net  ----DNS Query(53/UDP)----[100kbps] ---->
         ----    その他       ----[残り帯域]---->

こうしておけばDNSクエリが多大になっても他のサービスには影響しません。
ヤマハだとこんな感じでやります。

ISP---(PPPoE)---|[pp]----[QoS]|----->
               LAN2          LAN1
queue lan1 type shaping

queue lan1 class property 1 bandwidth=100k
queue lan1 class property 2 bandwidth=60m

queue class filter 1 1 ip * * udp * domain
queue class filter 2 2 ip * * * * *

これでDNSのクエリに使う帯域を100kbspに絞ることができます。そもそもDNSクエリは小さいのでそんなに帯域は要らないはずです。上記の例ではDNS以外のその他のトラフィックには60Mbpsを割り当てています。
ですが、この方法には欠点があります。DoSを食らった場合、それに帯域を占有され正常なリクエストもドロップしてしまいます。つまり、「普通に」自サイトに対しクエリしようとしているものまで落としてしまうことになります。
上の例ではLAN1側でQoSをかけていますが、実はこれには理由があります。単純な帯域制御であればLAN2側でかけてもいいのですが、ひと工夫してサービスをデグレードしないように設定を行います。

Dynamic Class Control(DCC)を使う

ヤマハの資料によれば、RTX5000,RTX3500,FWX120,RTX810,RTX1200,SRT100がこのDCCをサポートするようです。

(価格考えるとRTX810がお得??)

実はQoSをかける例のところでLAN2側を使わなかった理由がこのDCCです。本来ならばppに対してこのDCCが効けば良いのですが、現状のファームウェアではこれはサポートされてないようで、残念ながら「入り口」におけるDCCが作動しません。そこでLAN1側で行うようにしています。ルータの「中」を通るので性能的に食われる気もするのですが・・・
Dynamic Class Control(DCC)では制限された帯域を越えたホストをブロックする機能があります。これは単純なQoSとは異なり、帯域を食い過ぎてるホスト(IP)を一定時間蹴る機能です。
DoSの場合、一般的には攻撃してくる元のIPアドレスは不明です。不明どころか複数箇所からDDoSを食らうかもしれませんし、毎回、IPアドレスが異なるかもしれません。このため、単純なフィルターでは対応できません。LUAで書けば対応できるかもな気もしますが。
そこで、ヤマハのこのDCC機能を使って、多大なDNSクエリを投げてきたホストをブロックしてしまおうというわけです。
設定例は次のような感じです。

queue lan1 type shaping
queue lan1 class filter list 1 2
queue lan1 class property 1 bandwidth=100k
queue lan1 class property 2 bandwidth=60m
queue lan1 class control 1 forwarding=reject threshold=50%,15 time=900
speed lan1 100m

queue class filter 1 1 ip * * udp * domain
queue class filter 2 2 ip * * * * *

DCCでは「その条件」を越えたら次のクラスにリダイレクトするという機能がありますが、ここではブロック(forwarding=reject)します。上記の例ではDNSの帯域を100kbpsとし、その50%を15秒以上使う(threshold=50%,15)とブロックし、15分(time=900)経ったら解除するという設定です。この時の判断基準はデフォルトのソースIPとなり、帯域を食っているソースIPはブロックされるという挙動になります。
ブロックされているIPアドレスは show status qos dcc コマンドで見ることができます。