OXY NOTES

DNS Amp攻撃の解説と、踏み台にされないためのBIND DNSの設定

誰もが攻撃者側になる可能性のあるDNS Amp攻撃

古くからその危険性を指摘され、今だ被害が拡大しているDNS Amp攻撃。

DNSサーバの脆弱性を突かれてDNS Amp攻撃の踏み台にされないように、攻撃の詳細と対策についてまとめました。


DNS Amp攻撃について

多くのサイトで解説されているので、このページでは簡単にわかりやすく解説します。
Amp」とは「アンプ(増幅器)」のことです。
攻撃者はDNSへの問い合わせと、キャッシュ機能を利用してデータの量を増幅させます。そのデータを対象とするサーバへ送信することで、回線をパンクさせるDDos攻撃の一種です。

1.攻撃者は特定のサーバを乗っ取りDNSレコードの内容を書き換える

実際にDNS Amp攻撃攻撃に使われるゾーンファイルレコードの例

example.com.		21600	IN	A	1.1.1.1
example.com.		21600	IN	A	1.1.1.2
example.com.		21600	IN	A	1.1.1.3
example.com.		21600	IN	A	1.1.1.4
example.com.		21600	IN	A	1.1.1.5
example.com.		21600	IN	A	1.1.1.6
(以下同じような内容が百行ほど続く)

2.DNSサーバへ悪意あるキャッシュを作成

攻撃者はオープンリゾルバ状態のサーバへ、攻撃されたサーバの情報を問い合わせる。
(オープンリゾルバとは外部から問い合わせに応答するDNSキャッシュサーバのこと)

オープンリゾルバ状態のサーバは、攻撃されたサーバの悪意あるレコードを取得。攻撃者へ名前解決の結果を送信します。

この作業でオープンリゾルバ状態のサーバは、攻撃されたサーバの悪意あるレコードをキャッシュします。

3.攻撃対象に成りすまして問い合わせ

攻撃者が「攻撃対象のサーバになりすまして」オープンリゾルバ状態のサーバへ「攻撃されたサーバの情報」を問い合わせ。
問い合わせが本人からだと勘違いしたオープンリゾルバ状態のサーバは、攻撃者が作った悪意あるレコードのキャッシュを攻撃対象のサーバに送信

4.大量のデータが送信された攻撃対象は回線がパンク

同じようなオープンリゾルバ状態のDNSサーバから大量のDNSの情報が送信されてきて回線がパンク

以上の流れでDNS Amp攻撃は実行されます。


攻撃者側からみたDNS Amp攻撃のメリット

1.攻撃者の身元が詐称できる

DNSの問い合わせにはUDPが使われるため身元を詐称できます。攻撃された側もデータを送信してきているサーバは特定できるが、その原因を作った攻撃者を特定できません

2.攻撃が増幅できる

通常であれば大量のデータを送信して攻撃するためには、攻撃者側の回線も専有してしまいます。しかしDNS Amp攻撃だと80バイト程度の軽い問い合わせを、4000バイト程度まで増幅することができます。
実際にテストして計測すると、攻撃者の送信したデータの約40倍のデータ量が攻撃対象のサーバに送信されたそうです。

3.同時に大量のDNSから攻撃可能

調査によると世界中に130万ほどあるDNSサーバの75%はオープンリゾルバ状態とのこと。調べれば攻撃の踏み台に利用できるDNSサーバはすぐに見つかるため、同時に数百台のサーバからデータを送信することも可能です。

4.攻撃の対象者に有効な防御方法がない

急に世界中のDNSサーバから身に覚えのないデータが大量に送信されてくるので、多くの場合で対策が間に合わず、サーバがビジー状態か、最悪の場合停止してしまいます。

このようにDNSがオープンリゾルバの状態だと、このような犯罪行為の踏み台にされてしまいます。
簡単な設定で対策できるので、ぜひ対策しておきたいところです。


DNS Amp攻撃の踏み台にされないための設定

まず、混乱しないために、用語の確認をしておきます。
ドメイン名の問い合わせに対して、IPなどの情報を調べて応答するのをDNSキャッシュサーバ
自分のWebサイトのドメイン名とIPアドレスの情報をルートネームサーバなどに登録するのが権威ネームサーバです。

この内、どのIPからでもドメインの問い合わせに応答するDNSキャッシュサーバのことを、オープンリゾルバと呼びます。
まずは自分の設置しているDNSがオープンリゾルバ状態かどうかをチェックしてみましょう。

DNSサーバがオープンリゾルバ状態かどうかをチェックする方法

前提としてBINDでDNSキャッシュサーバ権威ネームサーバの両方を運営している場合を想定しています。
外部からの問い合わせを想定して、Windowsからnslookupを試します。
スタート」から「プログラムを指定して実行」の欄に「cmd」と入力してエンター。コマンドプロンプトを起動します。

$ nslookup ←nslookupコマンドを利用する
> server ns.example.com ←問い合わせサーバで自分のサーバへ接続
> set type=ANY ←問い合わせの種類でANYを指定
> example.com ←まずは自分のサーバで管理している情報を表示してみます

自分で設定したゾーンファイルの情報が表示されるはずです。(ここで問い合わせができない場合は権威ネームサーバとして稼働していない可能性があります。)
続いて管理外のDNS情報を問い合わせてみます。

> google.com ←google.comの情報を問い合わせ
*** ns.example.com が google.com を見つけられません: Query refused

以上のように「見つけられません」と出れば外部からの問い合わせに応答していません。もし先ほどと同じようにgoogleの情報を返してきたら、それはオープンリゾルバ状態で、いつ踏み台になってもおかしくない状態です。※

※nslookupを打っているネットワーク(IP)からの問い合わせを有効にしている場合は、応答したとしてもオープンリゾルバとは限りません。その場合は「OPEN RESOLVER TEST」を利用させてもらいましょう。

ここでIPアドレスをいれて、Statusclosedとなれば問題ありません。

BIND DNSサーバの設定

それでは早速BINDの設定をしていきます。設定ファイルは通常「/etc/named.conf」にあると思います。

vi /etc/named.conf

理解しやすいようにオープンリゾルバと関係の無い設定は省略しています。

acl my-network {
        # 問い合わせを許可するアドレスの指定
        192.168.100.0/24 ;
};
options {
        # BIND8の場合必要
        # fetch-glue no;

        # キャッシュサーバの場合yes
        recursion yes ;

        # 定義したネットワークからのアクセスを許可
        allow-query {
                localhost ;
                my-network ;
        } ;

        # それ以外のアクセスを拒否
        allow-transfer { none ; } ;
};
zone "example.com" {
        type master;
        file "/var/named/example.com.hosts";
        # optionsで拒否しているのでこのゾーンファイルに関しては外部からのアクセスを許可する設定
        allow-query { any ; } ;
};

1行目acl my-networkで問い合わせを許可するIPを指定して定義します。通常ローカルホスト等を指定します。

7行目fetch-glue noはBINDのバージョン8で必要な記述です。

10行目recursion yesでキャッシュサーバとして利用可能にする設定。

13行目から16行目のallow-queryでlocalhostと先ほど定義したmy-networkを指定。

19行目allow-transfer { none ; }で、それ以外のアクセスを全て拒否。

これで外部からの問い合わせには応答しなくなりますが、このままだと自分のサイトに関する問い合わせも拒否してしまいます。

25行目zone “example.com”の最後の行にallow-query { any ; }と追記して、自分のサイトのゾーンファイルに関する問い合わせは、どのIPからでも受け付けるという設定にします。

設定が完了したら再起動して設定を有効にします。

# /etc/init.d/named restart

再び外部から問い合わせをして、以下のように表示されるか確認してください。

*** ns.example.com が google.com を見つけられません: Query refused

また、許可したネットワークから名前解決ができるか調べるために、Tera Term等でサーバへ接続して、同じようにgoogleの問い合わせを行い、ゾーンファイルを正しく返すかチェックしておいてください。


キャッシュサーバとして利用しない場合

そもそもサイトの名前解決だけできれば良いので、権威ネームサーバとしてだけ動作すれば良いという場合も多いはずです。その場合はキャッシュネームサーバとしての機能を切ります。これが一番安全で簡単な対策です。
この場合、定義や許可などの設定は必要なく、「recursion no」とするだけです。

options {
        # BIND8の場合必要
        # fetch-glue no;

        # キャッシュサーバの場合yes
        recursion no ;

};
zone "example.com" {
        type master;
        file "/var/named/example.com.hosts";
};

以上でDNS Amp攻撃に対する対応は完了です。
簡単な設定で未然に防ぐことができるので、必ず設定するようにしてください。