今回はこの「DDoS攻撃対策 トリロジー」最終回だ。正直、このシリーズは人気がないよう見った。しかし、DDoS攻撃は、今日のあらゆるインターネットサービスにとって主なセキュリティ上の脅威であり、緊急時に対応できるように、事前に何を想定しているかを知っておくことが重要だ。
好かれようが好かれまいが、今回は最終回だった。将来的には、私は多分DDoS攻撃に関連する経験記事をこれ以上書くべきではないだ。それらの多くは、商業秘密だからだ。
今回の記事は、「HTTP(S) フラッド攻撃」の対策ですが、しかし今回は前回の「一般的なDDoS攻撃の対策」よりほとんど簡単だった。まず「HTTP(S) フラッド攻撃」を対策ため、必要のお金は前回より安くだ、そして、規模はともかく、方法は同じいだ。つまり「HTTP(S) フラッド攻撃」の防衛理念は全部同じだ。
同じに、今回の記事は大体は防衛の方法そして理念を教えれだけだ、だから、それが取得してすぐに使用することができるコードやプログラムを提供してない。
では、そろそろ始めましょう。
1. HTTP(S)フラッド攻撃対策基本概要
HTTP(S)フラッド攻撃の対策理念と一般的なDDoS攻撃は同じいに「防御コストには攻撃コストより低くされる。」だった。
しかし、と一般的なDDoS攻撃に違うのば、その理念は誰でもほとんど実現できる。
HTTP(S)フラッド攻撃を防衛は全部3種類の理論方法がある。
それは:
1. 速度制限系(アクセス頻度の制限)
2. マンマシン検証系
3. より高い代償を支払う系
Webサービスの種類にもよりますが、1つ種類の方法のみに適したサービスもあれば、3つ種類の方法で同時に利用できるサービスもあります。 そのため、Webサービスの種類に応じてメソッドを使い分ける必要がある。
でも、HTTP(S)フラッド攻撃を防衛する前に、様々の準備が必要だ。例えば、インフラ構造。
まず、私はソースサーバーのフロントエンドに専用のリバースプロキシサーバーを追加することを強くお勧めしまう。
これには2つの利点がある。
まず、**リバースプロキシサーバーにウェブアプリケーションファイアウォール(WAF)の機能を導入して、ソースサーバに十分な処理リソースを持たせるを本職なことにするができる。それに、こんな構築すれば、WAFも十分な処理リソースはHTTP(S)フラッド攻撃を防衛するた。**特にHTTPSフラッド攻撃、SSLのオフロードには、非常に大量のCPU処理リソースが必要だ。だからこそ、もしできれば、独立のリバースプロキシサーバーをつかってくれ。
そして、これにより、**後でパフォーマンスを簡単にスケーリングできる。**もし大き規模なHTTP(S)フラッド攻撃、攻撃リクエストの処理は全部リバースプロキシサーバーで対処するが、性能が足りないとき、我々はただの簡単にリバースプロキシサーバーを増加するでいい。
HTTPSフラッド攻撃にとって、一般的なはそんな方法を処理するですが、しかし特殊状況もある。特例状況例え、こ回の攻撃が、単一の攻撃元と多数のプロキシサーバーによって開始されるHTTPSフラッド攻撃である場合、もし攻撃のパケットメッセージの分析方法がわかるなら、攻撃されたデータパケットの特性値を分析し、ファイアウォールを直接使用してブロックすることができる。 これにより、SSLオフロード操作を実行する必要がなくなり、CPUリソースを節約した。
2. HTTP(S)フラッド攻撃対策解明
HTTP(S)フラッド攻撃対策は全部3種類の理論方法がある。それぞれは自分の適切な状況がある。では、各メソッドがどのようなシナリオに適しているのかを見てみよう。
2.1 速度制限(アクセス頻度の制限)
通常はソースサーバーを保護するためにアクセス速度の制限を設定している。 一般的な訪問者が1秒間に一度に多くのリクエストを送らないのも事実だ。
通常、アクセス速度を制限するには、nginxのlimit_reqコマンドを使用する。
例:
http {
limit_req_zone $binary_remote_addr zone=myreqzone:10m
limit_req_log_level warn;
server {
## 1つのIPにつき10接続に制限
## 通常、ブラウザは各ホストへの接続を2つまたは3つ開きます。
## トリガされた場合、503エラーを返します。
## 「nodelay」とは、ウォームアップをせずにまっすぐ上に上がることを意味します。
limit_req zone=myreqzone burst=10 nodelay;
}
}
同時に、アクセス速度の制限も、APIサーバーの唯一の保護方法だ。リクエストするAPI自体もプログラムであるため、マンマシン検証普通は無理だ。
ただし、アクセス頻度の制限は大体2つの問題がある。
まずはもし攻撃者はたくさんのプロキシサーバーを使いれば、アクセス頻度制限の効果はほとんどないだ。Nginxのアクセス頻度制限機能は基本にIPを使ってそれに判断するが、たくさんのプロキシサーバーを使いれば、その制限は無効だった。
そして、複数のリバースプロキシサーバーを利用してのばいは、単点のリバースプロキシサーバーのIP制限リストは自分だけ使う、であり、そのリストは他のサーバーとの同期はできない。そのせいで、アクセス速度制限の効果が弱くなる。
ですから、私の方法は、「Nginx-Lua」を使って、自分でアクセス頻度制限機能を構築する。まず、IPアドレスだけに頼るのではなく、クライアントIDを導入してを使ってに判断する。そして、アクセス頻度制限のクライアントリストは「Redis」を使って、全サーバークラスターで同期する。
2.2 マンマシン検証
上の図は、マンマシン検証のフローチャートだ。
DDoS攻撃は大体人間以外のアクセスするから、だから基本理論は**「このリクエストが本当に人がな?ここでチェックしよ。」**。
本当な人をサイトのアクセスは、きっとブラウザを使っている。だから、このリクエストは本当にブラウザからかどうか、チェックすれば直ぐわかる。
簡単に言えば、こればブラウザ検証。検証コード以外の方法はすべてブラウザ検証だった。ブラウザの特性を利用して、それに本当かどうかには検証する。
どの方法を使用しても、全方法のロジックフローは図のようになる。
どんな方法あるのか、みってみよう。
2.2.1 Set-Cookie検証
まずは、Set-Cookie検証法。
この方法はブラウザのCookie機能を利用して、そのままにブラウザ検証した。
ご存知のとおり、通常のブラウザはCookieにアクセスできる。そのため、クライアントが正常に戻るかどうかを確認するためにWAFはCookie情報を書き込もうとする。
じゃ、Nginxでその機能を実現するは、まず最初の簡単の例を見ろう:
server{
......
if ($cookie_check != "imnotrobot"){
add_header Set-Cookie "check=imnotrobot";
rewrite .* "$scheme://$host$uri" redirect;
}
......
}
これでは、簡単なCookie検証機能が完成した。
しかし、そのCookieの内容は固定されており、誰が見ても同じだ。これは簡単に逃げられてしまうので、いくつかの変数を追加するが必要だ:
server{
......
if ($cookie_check != "imnotrobot$remote_addr"){
add_header Set-Cookie "check=imnotrobot$remote_addr";
rewrite .* "$scheme://$host$uri" redirect;
}
......
}
これでは、Cookieの内容はクライアントのIPがある。
しかしそれでも、もし攻撃者本気に見れば、すぐに対策がある。ですから、一番いいの方法はそのCookieの内容をハッシュ操作にはソルト値を使用する。だけどう、Nginxの構成ファイルでそのハッシュ操作関係の関数がないですが、どうしましょう?
ここで、「Nginx Lua」をもう一度使って:
server{
......
rewrite_by_lua '
local cookie_info = ngx.md5("This is salt value" .. ngx.var.remote_addr)
if (ngx.var.cookie_check ~= cookie_info) then
ngx.header["Set-Cookie"] = "check=" .. cookie_info
return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri)
end
';
......
}
これでは、ハッシュ操作にはソルト値を使用しているのSet-Cookie検証機能が完全に完成した。
ただし、今までのHTTP(S)フラッド攻撃プログラムは4割このSet-Cookie検証法に対策していった。だから、この方法はもう絶対安全したを言われない。
2.2.2 JavaScript検証
Set-Cookie検証法ダメなら、じゃJavaScript検証法がどうっか?
ご存知のとおり、**通常のブラウザはJavaScriptを実行するができる。**そのため、Set-Cookie法は使わないて、JavaScriptをCookie情報を設定する。
server{
......
rewrite_by_lua '
local cookie_info = ngx.md5("This is salt value" .. ngx.var.remote_addr)
local jssetcookie = "<script>document.cookie=\"check=" .. cookie_info .. "\";location.reload();</script>"
if (ngx.var.cookie_check ~= cookie_info) then
ngx.print(jssetcookie)
ngx.exit(200)
end
';
......
}
これでは、JavaScriptバージョンのSet-Cookie検証機能が完全に完成した。
ただし、JavaScriptはできるなことはたくさんがある。Set-Cookieだけじゃなく、例えば「302ジャンプ検証」も一つの検証方法だ。ところで、CloudFlareのJavaScript検証方法は「文字列コンテンツの文字数の計算」。だから、どんな方法が使うのか、自分に創造しよう。
でも、JavaScript検証方法は攻撃者によってクラックされってもちろんできる。
2.2.3 検証コード
これは大技だ。
Set-Cookie検証法とJavaScript検証方法はただのブラウザを検証するだけ、しかし、検証コードは直接に本当な人かどうかこれをチェックする。
だけど、簡単な検証コードは、例え画像検証コード。画像認識機能は簡単的に画像検証コードをクラックする。
「Google reCAPTCHA」ような、解読しにくい検証コードの使用をお勧めする。
これからは、攻撃者の敵人はGoogleだった、私たちには関係ないだ。
2.3 攻撃者はより高い代償を支払う
「攻撃者はより高い代償を支払う」方法は、先の「マンマシン検証」だけに基づく進化的な方法です。
この方法は、もはや本当な人かどうかは関係ない、どうせ代償を払うんだろ。
以前、ある新しい検証コードサビース「Coinhive Captcha」がある。この「Coinhive Captcha」検証コードは暗号通貨「Monero」のマイニング計算を使用した検証コードサービスだ。この検証コードは本気に言えば本当な人かどうかは関係ない、代償を払っだったでいい。
これでは、攻撃側も大惨事になってしまう。「Coinhive Captcha」検証コードを実行すると、攻撃を継続することができず、すべてのCPUリソースを使い切ってしまう。 しかし、「Coinhive Captcha」検証コードを実行しないと攻撃を継続することもできない。だから、当時のDDoS攻撃に対しては、このCAPTCHAを使用することが非常に有効でした。
残念ながら、「Coinhive」は運営を停止した。
しかし、私たちはこのアイデアから学び、同様のサービスを自分たちで開発することができるんだ。もっと簡単言えば、支払い用のQRコードを直接入力して、支払いなしでアクセスを禁止することもできるんだ。
3. 結論
HTTP(S)フラッド攻撃の方法は以上だ。
できれば、今でも一般の方には「CloudFlare」の使用をお勧めする。検証コード機能は簡単にクリックしてすぐに有効する。
最後に、最も重要な点を説明する必要がある。DDoS攻撃に対する防御力がどれほど強力であっても、Webサービス自体のパフォーマンスが高くなければ、DDoS攻撃に対する防御の意味が全くないんだ。
以上。