
高速/低コスト CommonCrawl RegExp in Node.js
Image
WARCannonは、インターネットをgrepするプロセスを簡略化し、低コスト化するために構築されました。
WARCannonを使えば、以下のことが可能です:
WARCannonは、AWSテクノロジーを巧みに活用し、任意の容量に水平スケールし、スポットフリートと同一リージョンデータ転送でコストを最小化し、S3から驚異的な速度(ノードあたり最大100Gbps)でデータを取得し、数百のCPUコアにわたって並列化し、DynamoDBとCloudFrontを介してステータスを報告し、S3を介して結果を保存します。
全体として、WARCannonは約30ドルで数時間以内に400TBを超える複数の正規表現パターンを処理できます。
最も速く簡単に始める方法は、AWS CloudShellを使用することです。以下のワンライナーを貼り付けるだけです:
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/master/cloudshell/deploy.sh)
WARCannonのmaster以外のブランチを使用したい場合は、次のように入力します:
export GIT_BRANCH=branch_name
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/$GIT_BRANCH/cloudshell/deploy.sh)
注:CloudShellデプロイメントはエフェメラルストレージを使用するため、CloudShellが終了するとカスタム正規表現パターンが失われます。WARCannonを頻繁に使用する場合は、以下の「ローカルインストール」を推奨します。
WARCannonをインストールするには、以下が必要です:
プロのヒント: 物事をクリーンに保ち、AWS内の他のものと区別するために、新しいアカウントにWARCannonをデプロイすることを強くお勧めします。AWSの「Organizations」コンソールから新しいアカウントを簡単に作成できます。「強くお勧め」とは、『これを他のものの隣にインストールしないでください』という意味です。
まず、リポジトリをクローンし、サンプル設定をコピーします。
$ git clone [email protected]:c6fc/warcannon.git
$ cd warcannon
warcannon$ cp settings.json.sample settings.json
settings.jsonを好みに合わせて編集します:
必須設定
nodeInstanceType: 並列処理に使用するインスタンスタイプの配列。'c'タイプがこの目的には最も価値が高く、任意のサイズを使用できます。実際のキャンペーンには["c5n.18xlarge"]が推奨値です。nodeCapacity: 並列処理中に要求するノード数。結果のノードは、指定したnodeInstanceTypesの任意の分布になります。nodeParallelism: vCPUあたりの同時WARC処理数。2が適切な数値です。ノードのRAMがこの並列度で動作するのに不十分な場合('c'タイプのインスタンスで発生する可能性があります)、代わりに安全な最高の並列度で実行されます。nodeMaxDuration: コンピュートノードの最大寿命(秒)。ジョブがまだ完了していない場合、この時間後にノードは自動的に終了されます。デフォルト値は24時間です。オプション設定(使用しない場合は完全に省略)
sshKeyName: us-east-1に既に存在するEC2 SSHキーの名前。allowSSHFrom: SSHを許可するCIDRマスク。通常は<yourpublicip>/32になります。インストールするには、次を実行します:
$ npm install
$ npm link
$ warcannon deploy
WARCannonでキャンペーンを実行するには、以下のいくつかのステップで最もよく説明できるシンプルで簡単なワークフローを使用します:
warcannon deploywarcannon testLocal -swarcannon testwarcannon list 2022warcannon populate 2022-21warcannon firewarcannon syncResultsでS3から結果を取得各ステップの詳細については、以下をお読みください。
WARCannonは、AWS Open Dataプログラムを介してCommon Crawlからデータを供給されます。Common Crawlは、そのスパイダーが取得するデータがウェブサイトのテキストだけでなく、JavaScript、TypeScript、完全なHTML、CSSなどの他のテキストベースのコンテンツもキャプチャする点でユニークです。独自のコンポーネントを識別できる適切な正規表現を構築することで、研究者はウェブサイトが使用するテクノロジーを特定し、ウェブサイト自体に触れることなくこれを行うことができます。問題は、これには数百テラバイトのデータを解析する必要があり、どんなリソースがあっても困難な課題であることです。幸い、WARCannonにはこれを実現するためのいくつかのツールがあります!
インターネットのgrepは心臓の弱い人向けではありませんが、効果的なふるいから始めることが第一歩です。WARCannonは、実際のCommon Crawlデータに対して正規表現のローカル検証を可能にすることでこれをサポートします。まず、lambda_functions/warcannon/matches.jsを開き、regex_patternsオブジェクトを変更して、name: pattern形式で使用したい正規表現を含めます。デフォルトの検索セットからの例です:
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
この式に一致する文字列は、結果内の対応するキーの下に保存されます。この場合はaccess_key_idです。プロのヒント: RegExrを「JavaScript」形式で使用して、既知の良好な一致に対して正規表現を構築およびテストします。
また、指定したドメインからの結果のみをキャプチャするオプションもあります。これを行うには、含めたいFQDNでdomains配列を設定するだけです。これはほとんど価値がないため(節約される処理量は非常に小さい)、空の[]のままにしておくことをお勧めしますが、一部のニッチなケースでは有用です。
exports.domains = ["example1.com", "example2.com"];
matches.jsが準備できたら、次のコマンドを実行します:
warcannon$ warcannon testLocal -s
必要に応じて、commoncrawl S3バケット内のWARCへのパスを追加することもできますが、そうしない場合はハードコードされたデフォルトが使用されます。
WARCannonはWARCファイルをストリーム処理し(-sを省略した場合は完全にダウンロード)、設定された一致を見つけます。WARCannonは、ctrl+cで中断した場合、または処理が完了した場合に、結果を~/.warcannon/フォルダに保存します。これにより、最小限の帯域幅で一般的な一致を非常に迅速にテストすることが容易になります。
その上、WARCannonはローカルで実行する際に、正規表現の総計算コストを評価しようとします。これにより、キャンペーンを実行する前に、特定の正規表現がパフォーマンスに大きな影響を与えるかどうかを知ることができます。

単純な正規表現パターンだけでは不十分で、正しい情報を返すために追加の手順が必要な場合があります。この場合、同じキー名でexports.custom_functionsオブジェクトに関数を追加するだけで、任意の追加処理を実行できます。
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
exports.custom_functions = {
"access_key_id": function(match) {
// Ignore matches with 'EXAMPLE' in the text, since this is common for documentation.
if (match.text(/EXAMPLE/) != null) {
// Returning a boolean 'false' discards the match.
return false
}
}
}
注:WARCannonはバカみたいな速度でテキストを処理するように設計されています。 もちろん、任意の種類の操作を実行することは可能ですが、ネットワークコールなどの高レイテンシカスタム関数を追加すると、処理時間とコストが大幅に増加する可能性があります。ネットワークコールは、Webサイトに対する多数のコールを引き起こし、問題を引き起こす可能性もあります。これらの関数の使用方法には注意してください。
AWSのコストは、特に研究だけを目的としている場合には不安を誘発することがあります。WARCannonは、フルキャンペーンに加えて単発実行も可能にするように構築されているため、得られる結果に自信を持つことができます。testLocalで得られた結果に満足したら、更新されたマッチをデプロイし、クラウドバックアップテストを簡単に実行できます:
warcannon$ warcannon deploy
warcannon$ warcannon test
繰り返しますが、必要に応じてWARCパスを含めることもできますが、必須ではありません。
これにより、設定した正規表現を使用してLambda関数が同期的に実行され、即座に結果が返されます。このプロセスには約2.5分かかるため、その魔法が行われるのを待つことを恐れないでください。
Lambdaで得られた結果に満足したら、実際にインターネットをgrepする準備が整いました。まず、基本的なハウスキーピングを確認してから、開始します。
WARCannonはAWS Simple Queue Serviceを使用して、コンピュートノードに作業を分散します。以前の実行で結果が汚染されないようにするために、WARCannonにキューを空にするよう指示できます:
warcannon$ warcannon emptyQueue
[+] Cleared [ 15 ] messages from the queue
その後、キューの状態を確認できます:
warcannon$ warcannon status
Deployed: [ YES ]; SQS Status: [ EMPTY ]
Job Status: [ INACTIVE ]
Active job url: https://d201offlnmhkmd.cloudfront.net
進む前に以下を確認してください:
コンピュートノードが消費するキューメッセージを作成するには、まずSQSにクロールデータを投入する必要があります。WARCannonには、利用可能なスキャンを表示する機能から始めて、これに役立ついくつかのコマンドがあります。この場合、2021年に利用可能なスキャンを確認してみましょう:
warcannon$ warcannon list 2021
CC-MAIN-2021-04
CC-MAIN-2021-10
「2021」という文字列に一致する2つのスキャンがあります。これらのスキャンの1つに基づいてキューを投入するようWARCannonに指示できます。今回は、スキャンの1つを一意に識別するパラメータを指定する必要があります。「2021-04」で問題ありません。チャンク数とチャンクサイズを指定して部分的なスキャンのみを投入することもできますが、今はスキップします。
warcannon$ warcannon populate 2021-04
{Created 799 chunks of 100 from 79840 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
デプロイ時に、WARCannonはAthenaにデータベース(warcannon_commoncrawl)とワークグループ(warcannon)を自動的にプロビジョニングし、CommonCrawlから情報を迅速にクエリするために使用できます。これは、特定のクエリに基づいてスパースなキャンペーンを投入する場合に特に便利です。たとえば、次のクエリは「example.com」からの応答を含むWARCを検索します:
SELECT
warc_filename,
COUNT(url_path) as num
FROM
warcannon_commoncrawl.ccindex
WHERE
subset = 'warc' AND
url_host_registered_domain IN ('example.com') AND
crawl = 'CC-MAIN-2021-04'
GROUP BY warc_filename
ORDER BY num DESC
Athenaコンソールを使用して結果を微調整できますが、それを使用してジョブを投入する場合は、WARCannonコマンドラインからクエリを実行する必要があります:
warcannon queryAthena "SELECT warc_filename, COUNT(url_path) as num FROM warcannon_commoncrawl.ccindex WHERE subset = 'warc' AND url_host_registered_domain IN ('example.com') AND crawl = 'CC-MAIN-2021-04' GROUP BY warc_filename ORDER BY num DESC"
[+] Query Exec Id: 0319486e-1846-491c-badf-2e23ae213974 .. SUCCEEDED
WARCannonは、クエリの結果を使用してキューを投入し、結果セットのwarc_filename列に基づいてこれを行います。そのため、この列をgroup byするか、distinct()を使用して重複を避けることをお勧めします。このフィールドが存在しない場合、WARCannonはエラーをスローします。populateAthenaコマンドにクエリ実行IDを渡すことで、Athenaの結果をキューに投入します。
warcannon populateAthena 0319486e-1846-491c-badf-2e23ae213974
{Created 26 chunks of 10 from 251 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
注:単一ドメインのスパースジョブを投入することは良いアイデアのように思えるかもしれませんが、多くの場合はそうではありません。 単一ドメインからの応答は、WARCの大きなサブセット全体に広く分散する傾向があります。これは、上記の例のクエリを使用して、各WARCの約150,000レコードのうち、中規模のWebサイトでの最大単一ヒットが1桁になる可能性があることを明確に確認できます。
キューが投入されたら、発射の準備が整いました。WARCannonは、すべてが正常であることを確認するためのいくつかの健全性チェックを実行し、キャンペーンの設定を表示し、注文を確定する前に最後の中止の機会を提供します。
warcannon$ warcannon fire
[!] This will request [ 6 ] spot instances of type [ m5n.24xlarge, m5dn.24xlarge ]
lasting for [ 86400 ] seconds.
To change this, edit your settings in settings.json and run warcannon deploy
--> Ready to fire? [Yes]:
「Yes」と応答してトリガーを引きます。
--> Ready to fire? [Yes]: Yes
{
"SpotFleetRequestId": "sfr-03dd32b8-51f7-4c8e-802b-a702fc3c8c95"
}
[+] Spot fleet request has been sent, and nodes should start coming online within ~5 minutes.
Monitor node status and progress at https://d201offlnmhkmd.cloudfront.net
応答には、キャンペーンの進行状況と各ノードのパフォーマンスを監視できる固有のステータスURLへのリンクが含まれています。

WARCannonの結果はJSON形式でS3に保存され、結果を生成した各ノードごとに分割されます。Athenaの結果は同じバケットの/athena/プレフィックスの下に保存されます。syncResultsコマンドを使用して、キャンペーンの結果をローカルマシンの~/.warcannon/フォルダに同期できます。
warcannon syncResults
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
...
その後、clearResultsで結果バケットを空にできます。
warcannon clearResults
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
...
[+] Deleted [ 21 ] files from S3.
質問がありますか?助けが必要ですか?貢献したいですか?勝利を自慢したいですか?Discordでお越しください!