まえがき
皆さんの中には最近、特にai-classとml-classのスタンフォードコースを受講している人もいるでしょう。 ただし、
Matlab
/
Octave
でいくつかのビデオ講義を視聴したり、クイズの質問に答えたり、多数のプログラムを書いたりすることは、実践で得た知識を適用し始めることの1つです。 Andrew Ngから得た知識が、 dft 、 特殊相対性理論 、 オイラーラグランジュ方程式が失われた私の脳の同じ暗い隅に落ちないように、私は研究所の間違いを繰り返さないことを決め、知識が私の記憶にまだ新鮮である間、可能な限り練習します。
それからちょうどDDoSが私たちのウェブサイトに到着しました。 admin-programmer(
grep
/
awk
/ etc)の方法や、機械学習技術の使用に頼ることができたのを防ぐことができました。
次に、Python 2.7 / PyBrainでニューラルネットワークを作成し、DDoSから保護するためのその使用について説明します。
はじめに
私たちが持っているもの:平均ボットネット(20,000-50,000)とそこからのaccess.logを持つDDoSの下のサーバー。 DDoSを開始する前にaccess.logを持つことは非常に便利です。 これは、正当なクライアントのほぼ100%を記述しているため、ニューラルネットワークをトレーニングするための優れたデータセットです。
取得したいもの:access.logのエントリによれば、ボットまたは人からのリクエストの発信元をある程度の確率で示す分類子。 この分類子のおかげで、攻撃ベクトル(サブネットのセット)を形成し、それらをファイアウォール/ホストに送信できます。
準備する
分類子をトレーニングするには、「悪い」クエリと「良い」クエリの2つのデータセットが必要です。 はい、ボットを見つけるために、まずボットを見つける必要があるのはかなり面白いです。 ここでは、たとえば、多数の503エラー(レート制限nginx)を持つIP'shnikovからのすべてのリクエストをログから抽出するために、grepが必要です。
その結果、3つのaccess.logを取得する必要があります。
- DDoSを開始する前のaccess.logからの「良好な」リクエストを含むデータセット
- 前の手順でスコア付けされた「不良」クエリを含むデータセット。
- データセット。分類する必要があり、リクエストを良いものと悪いものに分けます。 通常、これはDDoSの下のサーバーからの
tail -f
access.logです。
次に、いわゆるを解析する方法を学ぶ必要があります 結合されたnginxログ。 確かにインターネットのどこかに既製のレギュラーがありますが、私は自転車を発明しました:
(?P<ip>[0-9.:af]+) [^ ]+ [^ ]+ \[.*\] "(?P<url>.*)" (?P<code>[0-9]+) (?P<size>[0-9]+) "(?P<refer>.*)" "(?P<useragent>.*)"$
/ *
yet another log parser
を作成したという事実により、私はjsonでのログの初期シリアル化のアイデアをもう一度思い出しました。 * /
ログの解析方法を学習した後、フィーチャ(フィーチャ/マーカー/フィーチャ)を選択し、辞書をコンパイルし、それを使用して各データセットレコードのフィーチャベクトルを作成する必要があります。 これについては後で詳しく説明します。
機械学習全般
ログから機能を強調表示することに決めました。そのために、「良い」ログと「悪い」ログを取得し、それらのすべての種類の機能、つまりサインを見つけようとしました。 結合されたログにはそれらの多くはありませんが、私は次を取りました:
- 要求自体(要求タイプ(
HEAD
/GET
/POST
/など)、url
およびhttp_version
とhttp_version
ます)。Url
、プロトコル、ホスト名、パス、およびquery_string
すべてのキーについて解析されquery_string
-
Referer
はリクエストのurl
と同様に解析されます。 -
User-Agent
、その形式がブラウザごとに大きく異なるため、魔法のストリートマジックと組み合わされています。 RFC2616はそれについてほとんど語っていません。 きっとずっといい。 -
status
、コード503/404/403の場合のみ。 一般に、DDoS中、サーバーは500/502に応答することを好むため、上記のコードのみを考慮します。
/ *ところで、DDoSから保護するために使用したスクリプトの最初のバージョンには悪意のあるバグが含まれていたため、約半分の兆候が考慮されていませんでした。 ただし、この状態でも、コードは非常にうまく機能し、そのおかげでバグ自体が長い間隠されていました。 アンドリューは、この点で非常に正しいことがわかり、勝つのは最も賢いアルゴリズムではなく、より多くのデータを供給するアルゴリズムであると言いました。 * /
そのため、リクエストに含まれる可能性のあるすべての種類の機能の膨大なリストを手にした瞬間になりました。 これが私たちの辞書です。 辞書は、可能なリクエストから
feature-vector
を作成するために必要です。 バイナリ(0と1で構成される)M次元ベクトル(Mは辞書の長さ)。これは、クエリ内の辞書の各属性の存在を反映します。
辞書がデータ構造の観点からハッシュテーブルである場合、辞書
if word in dictionary
ように多くの呼び出しがあるため、非常に良いです。
詳細については、 講義ノート11:機械学習システムの設計を参照してください
辞書と特徴ベクトルを構築する例
良い例と悪い例の2つの例だけでニューラルネットワークをトレーニングするとします。 次に、テスト記録でアクティブ化を試みます。
「不良」ログの記録:
0.0.0.0 - - [20/Dec/2011:20:00:08 +0400] "POST /forum/index.php HTTP/1.1" 503 107 "http://www.mozilla-europe.org/" "-"
「良い」ログから記録します。
0.0.0.0 - - [20/Dec/2011:15:00:03 +0400] "GET /forum/rss.php?topic=347425 HTTP/1.0" 200 1685 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9) Gecko/2008052906 Firefox/3.0"
結果の辞書:
['__UA___OS_U', '__UA_EMPTY', '__REQ___METHOD_POST', '__REQ___HTTP_VER_HTTP/1.0', '__REQ___URL___NETLOC_', '__REQ___URL___PATH_/forum/rss.php', '__REQ___URL___PATH_/forum/index.php', '__REQ___URL___SCHEME_', '__REQ___HTTP_VER_HTTP/1.1', '__UA___VER_Firefox/3.0', '__REFER___NETLOC_www.mozilla-europe.org', '__UA___OS_Windows', '__UA___BASE_Mozilla/5.0', '__CODE_503', '__UA___OS_pl', '__REFER___PATH_/', '__REFER___SCHEME_http', '__NO_REFER__', '__REQ___METHOD_GET', '__UA___OS_Windows NT 5.1', '__UA___OS_rv:1.9', '__REQ___URL___QS_topic', '__UA___VER_Gecko/2008052906']
テスト記録:
0.0.0.0 - - [20/Dec/2011:20:00:01 +0400] "GET /forum/viewtopic.php?t=425550 HTTP/1.1" 502 107 "-" "BTWebClient/3000(25824)"
彼女の
feature-vector
:
[False, False, False, False, True, False, False, True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False]
feature-vector
が
sparse
注意してください-この動作はすべてのクエリで観察されます。
データセット部門
dataset
をいくつかの部分に分割することをお
dataset
します。 私は70/30の割合で2つのパートに勝ちました:
-
Training set
。 その上で、ニューラルネットワークをトレーニングします。 -
Test set
。 ニューラルネットワークがどれだけよく訓練されているかを確認します。
このようなパーティションは、最小の
training error
(
training set
エラー)を持つニューラルネットワークが新しいデータに大きなエラーを生成するという事実によるものです。これは、ネットワークを「再トレーニング」し、トレーニングセットの下でそれをシャープにするためです。
将来、最適な定数の選択に困惑する必要がある場合、
dataset
を60/20/20の比率で3つの部分に分割する必要があります:
Training set
、
Test set
、および
Cross validation
。 後者は、ニューラルネットワークの最適なパラメーター(たとえば、
weightdecay
)を選択するのに役立ちます。
特にニューラルネットワーク
テキストログはもう手元にありませんが、
feature-vector
マトリックスのみが用意されたので、ニューラルネットワーク自体の構築を開始できます。
構造の選択から始めましょう。 2つの入力層のサイズの1つの隠れ層からネットワークを選択しました。 なんで? それは簡単です:どこから始めればいいのかわからない場合に備えて、 Andrew Ngは遺言を残しました。 トレーニングスケジュールを作成することで、後でこれを試すことができると思います。
隠れ層の活性化関数は、長い苦しみのシグモイドであり、出力層のSoftmaxです。 後者はあなたがしなければならない場合に選択されます
相互に排他的なクラスを持つマルチクラス分類。 たとえば、「良い」リクエストをバックエンドに送信し、「悪い」リクエストをファイアウォールで禁止し、「グレー」リクエストを送信してキャプチャを解決します。
ニューラルネットワークはローカルミニマムになる傾向があるため、私のコードでは、いくつかのネットワークを構築し、
Test error
が最小のものを選択し
Test error
(これは
trainig set
ではなく
test set
エラーであることに注意してください)。
免責事項
私は本当の溶接工ではありません。 機械学習については、mlクラスとaiクラスから学んだことしか知りません。 私は比較的最近pythonでプログラミングを開始しました。以下のコードは約30分で書かれており(ご存じのとおり、時間は尽きていました)、将来的にはファイルをわずかにファイルするだけでした。
コード
スクリプト自体は小さく、フォントに応じて2-3 A4ページです。 ここで見つけることができます: github.com/SaveTheRbtz/junk/tree/master/neural_networks_vs_ddos
また、このコードは自給自足ではありません。 彼はまだスクリプトバインドが必要です。 たとえば、IPがX分間にN件の不良リクエストを行った場合、ファイアウォールでそれを禁止します。
性能
- lfu_cache。 要求の処理を大幅に高速化するために、ActiveStateに移植された「高頻度」。 欠点-メモリ消費量の増加。
- PyBrainは突然pythonで記述されているため、あまり高速ではありませんが、ネットワークの作成時に
Fast=True
指定されている場合、ATLAS-based
arac
モジュールATLAS-based
使用できます。 これについての詳細はPyBrainのドキュメントで読むことができます。 - 並列化。 私はニューラルネットワークをかなり「厚い」サーバーNehalemでトレーニングしましたが、そこでもシングルスレッドトレーニングの欠陥が感じられました。 ニューラルネットワークのトレーニングの並列化のトピックを振り返ることができます。 簡単な解決策は、複数のニューラルネットワークを同時に並行してトレーニングし、それらの中から最適なものを選択することですが、これによりメモリに追加の負荷がかかり、これもあまり良くありません。 もっと普遍的なソリューションが欲しいです。 ml-classの理論的基礎全体がかみ砕かれているので、おそらくCですべてを単純に書き換えることが理にかなっています。
- メモリ消費と機能の数。 優れたメモリ最適化は、標準のPython配列からnumpy配列への移行でした。 また、辞書のサイズを小さくしたり、PCAを使用したりすることは非常に役立ちます。詳細は以下をご覧ください。
未来のために
- ログの追加フィールド。
combined
ログにさらに多くを追加できます。ボットの識別に役立つフィールドを検討する価値があります。 非国際的なWebプロジェクトでは、中国のユーザーがボットである可能性が最も高いため、IPアドレスの最初のオクテットを考慮することは理にかなっています。 - 主成分分析 。 これにより、
feature-vector
次元が大幅に削減され、ニューラルネットワークのトレーニング時間が短縮されます。 - 機能の前処理/正規化。 たとえば、正規表現
[a-fA-F0-9]{32}
__MD5__
はすべて、単語__MD5__
、単語__MD5__
含む日付のように見えるものなどに置き換えることができます。したがって、辞書のサイズ。 - ニューラルネットワークの定数と構造の調整。 現在のものは天井から、つまりPyBrainに基づいた分類子を作成するためのマニュアルから取得されました (そう、覚えておいて、私はコードがすっごく速く書かれたことを書きました)。
matplotlib
手元にあるため、異なるパラメーター値のニューラルネットワークトレーニンググラフを描画することは理にかなっています。 - オンライントレーニング。 賢い攻撃者の戦略はしばしば変わります。 外出先でニューラルネットワークを事前/再トレーニングする方法を考え出すといいでしょう。 ただし、これは言うよりも簡単です。
続きを読む
機械学習の講義ノート -mlクラスコースのエントリ。
UFLDL-教師なし機能学習および深層学習。 Andrew Ng教授からも。
結論の代わりに
highloadlabなどの実際の溶接機がどのように分類問題を解決するのに適しているかは非常に興味深いです 。 しかし、彼らのアルゴリズムはYandexのランキング式シリーズの謎であると私は言います。