リクルートのSOCによるログ基盤クラウド化検討プロジェクトの概要や失敗談、そこから得た学びを紹介する連載。今回は、EC2インスタンスとしてSplunkを構築する上でハマったポイントや、「最適」と考えるアーキテクチャについて。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
本稿公開時に、記事の一部に不正確な箇所があったので、表現を見直しました(編集部)。
セキュリティオペレーションセンター(SOC)によるログ基盤クラウド化検討プロジェクトの概要や失敗談、そこから得た学びを紹介する本連載「セキュリティログ基盤クラウド化検討大解剖」。前回は、ログ基盤クラウド化検討プロジェクト(以降、本プロジェクト)の背景や概要、クラウドを検討した理由、その中でもAmazon Web Services(AWS)を検討した理由を紹介しました。
今回は、AWSに「Amazon EC2」のインスタンスとして「Splunk」ログ基盤を構築する上で、ハマったポイントにも触れながら、われわれが「最適」と考えるアーキテクチャについて、主に技術的な観点で解説します。
前回の再掲ですが、下図のスケジュールでプロジェクトを推進しました。
本稿では、【3】機能検証と【4】取り込み/検索性能検証を中心に紹介します。【3】機能検証ではログの取り込み方式やSmart Storeの設定方法や動作を中心に、【4】取り込み/検索性能検証ではログの取り込み性能とSmart Storeの検索性能を確認しました(【6】〜【8】の検証内容や結果については、次回触れる予定です)。
今回の検証を実施するに当たって、下記の構成としました。
弊社では、セキュリティ監視で利用するログをストリーム処理で、監査レポートで利用するログを日次のバッチ処理でSplunk基盤に取り込んでいます。本検証では、ストリーム処理での取り込み(以降、リアルタイムログ取り込み)に「Amazon Kinesis Data Firehose」(以降、KDF)を使って、バッチ処理での取り込み(以降、バッチログ取り込み)に「Splunk Add-on for Amazon Web Services」を使いました。
このアドオンはSplunk社によって開発され、公式にサポートされています。詳細については公式サイトをご参照ください。
今回の構成では、AWSのマネージドサービスを有効に使うことで可用性や性能などといった管理すべきポイントを減らして、運用負荷の軽減を狙いました。また、取り込み対象のデータを「Amazon Simple Storage Service」(以降、S3)に集約することによって、不測の事態における再取り込みや同じデータを持った環境を、容易に何面でもビルド&スクラップできる設計としています。
下記は、使用したインスタンスです。
ログの取り込みには、オンプレミスで利用しているログを幾つかサンプリングして使用しました。使用したログは下記の通りです。
まずは、リアルタイムログ取り込みのアーキテクチャを解説します。ストリーミング処理が可能でSplunkと連携可能なマネージドサービスを検討した際、候補として上がったものがKDFでした。そこで、KDFを使用した取り込み方法の確認と仕様を確認しました。
「fluentd」を使って、アップロードマシンからKDFにデータを転送しました。KDFでは、期間またはデータサイズでバッファーして、エンドポイントに指定した「Classic Load Balancer」(以降、CLB)にデータを送信するとともに、S3にもデータをバックアップできるようにしました。CLBはHTTP Event Collector(通称「HEC」)で、Indexer(またはHeavy Forwarder)に分散してデータ送信します。
KDFの宛先にSplunkを指定した場合、S3にバックアップするためのバッファー期間やサイズを指定できますが、Splunkにデータを送信するまでのバッファー期間やサイズを指定することはできませんでした。データを送信してみた結果、リアルタイム性を期待していたもののインデクシングされるまでに数十秒〜1分程度の時間がかかりました。
また、S3にバックアップされているデータから再取り込みを実施する場合、「どのログファイルに再取り込みしたいイベントが含まれているか」を判断しにくいという課題を得ました。データの重複取り込みを防ぐために、既にSplunkに取り込まれたデータを、期間を絞って削除して、再度同じ期間のデータ取り込むことを想定していました。しかし、この方式では不測の事態のリカバリーには対処が難しいことが分かりました。
次は、バッチログ取り込みのアーキテクチャについてです。
バッチログ取り込みには、アドオンに含まれている「SQS-Based S3 inputs」を使いました。このアドオンを利用してS3からデータを取り込むには3通りの方式があります。本検証で利用したログは、AWSサービスの出すログではなく、カスタムログと分類されるログ種別です。このカスタムログを取り込むことができて、スケールアウト構成が取れる方式はSQS-Based S3 inputsのみでした。
取り込み時の各コンポーネントの連携図は下記の通りです。
S3にデータがアップロードされると、S3イベント通知で「Amazon Simple Notification Service」(以降、SNS)に通知され、メッセージが「Amazon Simple Queue Service」(以降、SQS)のメッセージキューにたまります。メッセージ内にはアップロードされたログデータのS3保存場所がパスで記載されており、Heavy Forwarder(以降、HF)はメッセージ内のパスを確認して、S3にデータを取りにいきます。
ログデータがS3にアップロードされてからSNSとSQSを経由し、HFでデータを処理するため、インデクシングされるまでにそれなりの遅延が発生することを想定していました。しかし、いざ検証してみると、想定よりも遅延は少なく、数秒程度で取り込みが完了する結果となりました。また、Splunk内に取り込まれたログデータが、どのファイルに含まれているか明確なため、再取り込みが容易であったこともうれしいポイントでした。
以上の結果からログの取り込み方式について、当初想定していた方式から見直しを図ることとしました。詳細については後述します。
前回少し触れましたが、弊社ではSplunkをフォレンジック業務にも活用しています。フォレンジック業務では、監視と比べると比較的長期間にわたる年単位のログを保管するので、数十TBのディスク容量が必要になるケースがあります。
「Smart Store」は、S3の非常に安価なオブジェクトストレージをSplunkのデータ保管領域として使える機能です。EC2インスタンスの高価な「Amazon Elastic Block Store」(以降、EBS)に年単位でTBクラスのデータを保管する必要がないので、保持すべきデータ量が増えれば増えるだけコスト削減が図れる利点があります。
下図は、Smart Storeを使用した場合と使用しない場合のコスト比較です。1カ月当たり48万円近いコスト削減効果が期待できそうだと分かりました。
また、S3は使用量の上限がないので、「ストレージの空きがなくなって必要な保持期間を保証できない」という問題が起きません。この2つの圧倒的な優位性に魅力を感じつつも、「本当にそんなことが可能なのか?」と疑問を抱えながら、Smart Storeの技術検証を決断しました。
われわれが想定するSmart Storeの用途は、主にフォレンジック業務などのデータ保持期間が長期間になるものとして、監視業務のように必要なデータが比較的短期間であり、即時性が求められるものについてはインデックスを別にして、EBSに保持することにしました。
ここで少しSmart Storeのアーキテクチャと動作について触れます。下図は、データ取り込み時の処理フローです(参考:【GOJAS Meetup-10】Splunk:Smart Storeを使ってみた)。
Splunkのインデックスには「バケツ」という概念があり、デフォルトでHotバケツ、Warmバケツ、Coldバケツという3種類のバケツが存在します。Hotバケツは新しいデータが格納されるバケツです。次のWarmバケツは、Hotバケツから一定期間過ぎたデータが格納され、Coldバケツはアクセス頻度の低くなった古いデータがWarmバケツから移動してきます。
WarmバケツとColdバケツは読み取りのみ可能なバケツです。Smart Storeを使用すると、仕様によりHotバケツとWarmバケツのみでColdバケツは存在しなくなります。バケツがHotからWarmにローテーションされた際に、S3にアップロードされる仕組みとなっており、Warmバケツは、S3とローカルディスク上のキャッシュ領域に保持されます。
ではキャッシュ領域からデータが削除されるタイミングがいつかというと、設定したしきい値にローカルディスクの使用量が達した際に、S3にアップロード済みのキャッシュが削除されます。キャッシュポリシーの設定として、キャッシュの保持期間に関する設定がありますが、ローカルディスクの使用量がしきい値に達していないとキャッシュは削除されません。削除するデータの優先順位には、幾つかのロジックが存在します。詳細は、性能検証のパートで後述します。
取り込むデータ量が増加した際は、ローカルディスクに保管されている期間が短くなりますが、S3に保管されているので、ディスクがいっぱいになってもデータをロストすることはありません。
続いて、検索時のSmart Storeの処理フローを説明します。検索時は、最初にローカルディスク内のデータを探し、存在しない場合はS3にデータを探しに行きます。S3に対象データが存在する場合は、ローカルディスクのキャッシュ領域にデータをダウンロードし、Search Headにデータを渡します。キャッシュ領域にダウンロードされたデータは指定期間後に削除されます(参考:【GOJAS Meetup-10】Splunk:Smart Storeを使ってみた)。
Smart Storeの性能について、検証前は疑いを持っていました。検索の際にキャッシュ領域に存在しないデータに関しては、S3から都度ダウンロードが発生するので、大幅に検索性能が下がるのではないかと仮説を立てて検証しました。
Smart Storeの性能については、検索にかかったEvent Per Second(EPS)や時間を評価軸としました。検索パターンには、ある期間の特定のデータセットにおいて10%以上のデータが検索条件にヒットする「Denseサーチ」を選択しました。
検証シナリオには、全てキャッシュ領域から検索にヒットするパターンとS3も含んで検索にヒットするパターンを採用しました。
両者の比較の結果、多少検索実行時間が延びたものの、想定していたような大幅な性能劣化は見られませんでした。
今回の検証の中で一番苦労したのが、このSmart Storeの性能検証でした。
まずSmart Storeのキャッシュポリシーの設定においては、「最近使用されていないバケツから削除する」というポリシーがデフォルトで適用されています。このポリシーは「Splunkサポートに相談せずに変更すべきではない設定」とされています。
本検証の計画時点では、全データをS3から取得するケース、半分程度S3から取得するケース、全データをキャッシュ領域から取得するケースの3パターンで実施することを想定していたので、このポリシーが大きな障壁となりました。「最近使用されていないバケツ」はすなわち、「最近検索がかけられていないバケツ」です。そのため、一度検索にヒットするとキャッシュ領域にデータが残ってしまい、想定したシナリオが実施できなくなりました。
具体的には、「全データをS3から検索したいのに、キャッシュ領域にも検索がかかってしまう」というトラブルです。その結果、何度もシナリオを見直し、検証対象期間を適宜変えて全てキャッシュ領域から検索するケースと、S3も含んで検索するケースを作り、比較的シンプルなシナリオに変更しました。
データがキャッシュ領域に存在するのか、S3に存在するのかを事前に把握する必要があったので、Splunkの「dbinspect」コマンドを使って、キャッシュ領域に存在しないデータを選定しました。
監査レポートに利用するログデータは毎日、かなりの容量をバッチ処理で取り込んでいます。アドオンを使う際、どこがボトルネックになる可能性があって、取り込みにどれくらいの時間がかかるのか(バッチウィンドウ内に終わるのかどうか)、性能をスケールさせるにはどのような手段が効果的なのかを検証で確認しました。
具体的な検証シナリオは下記の通りです。
S3上のデータは、AWSリージョン内の複数ゾーンに冗長化かつ分散されて保管されています。そのため、「小さいファイルを多く作ることで処理が広く分散されHFにダウンロードする際の性能が上がるのではないか」と考え、1ファイル当たりのサイズを変更して検証しました。
SQSについては、レーンの数が性能に影響を与えるのかを確認することで、HFの台数を決定する上での参考値になることを考えて、シナリオを複数ケースとしました。HFのスケールアウトとスケールアップは、HFの拡張方式を決める上でスケールアップとスケールアウトのどちらが性能向上に効果があるのかを確認するために、こちらも幾つかのケースで検証しました。
パイプラインセットは、Splunkがデータを受け取ってからインデクシングするまでの一連の処理を指します。パイプラインセットを増やすことで、この一連の処理の並列度を上げることができますが、その分CPUコアが追加で使われます。「HFやIndexerのパイプラインセットを増やすことでどれほど性能が向上するのか」を評価しました。
検証結果は下記の通りです。
性能に影響を与えたのは、SQSのレーン数とHFの台数でした。SQSのレーン数が増えると、取得対象のデータが複数のレーンに分散して、取り込みにかかる時間が増大してしまいました。HFの台数を増やすと、取り込みにかかる時間が短くなりました。しかしHFが4台になった時点で、ログ転送先のIndexerのCPUが高止まりしてしまいました。
取り込み時におけるIndexerのCPUコアの使われ方ですが、CPUコアはSplunkのパイプラインで並列に使用されるのではなく、入れ替わりで使用されていることが分かりました。うまくマルチコアで並列処理するわけではないので、1コアの周波数が高いマシンの方が全体として取り込み性能を発揮できるという仮説を得ました。
これまでの検証結果を踏まえて、改めて「AWSでSplunkを構築する場合はどういった構成とするのがよいのか」についてアーキテクチャ設計を見直しました。
変更点としては、ログの取り込み方式をSQS-Based S3 inputsに一本化しました。「SQS-Based S3 inputsの取り込みが想定以上に高速なこと」「KDF方式から切り替えても弊社のバッチウィンドウ内に収まること」「ログの再取り込みが容易なこと」「アーキテクチャをシンプルにすることで運用の複雑さを回避できること」などがその主な理由です。
上記のアーキテクチャを構築する上で、良さそうなインスタンスタイプは下記の通りです。
今回、Smart Storeの性能検証を実施したので、Splunk社が公開している技術情報に沿って、「i3」インスタンスでIndexerを構築しました。このインスタンスタイプは、キャッシュ領域であるローカルディスクのストレージのI/O性能を重視したスペックです。その代わり、CPU周波数が2.30GHzと、比較的CPU性能が低くなっています。そのため、バッチログ取り込みを実施した際に、CPUが性能のボトルネックになってしまいました。また、「1サーチ1CPUコア」というSplunkの検索アーキテクチャを考慮すると、「検索性能を上げるためにはCPU周波数の高いマシンにする必要がある」という結論に至りました。
AWSの場合、仮想マシンのローカルディスクの多くはEBSです。本検証時におけるEBSは汎用(はんよう)SSDの「gp2」というボリュームタイプが標準セットでした。EBSは1GB当たり3IOPSです。容量が増えるごとにIOPSの値は大きくなります(最大1万6000IOPSまで)。
Splunk社が公式に開示している、Smart Storeを使用する場合の推奨ストレージは、SSDまたはNVMeです。そのため、弊社の使用方法やデータ量なら、EBSであってもSmart Storeで使用するIOPS性能をまかなえると考えています。
IndexerはCPU周波数の高い「c5」インスタンスで構築して、バッチログ取り込みのボトルネックを解消した上でSmart Storeを使う構成にすることで、最適な費用対効果が得られると考えています。
本稿では、構成や実際の検証項目、またAWS上でSplunkを構築するにはどういった構成がよいかについて、検証結果を交えて解説しました。
次回は、運用性などを踏まえた上で、先述したAWS上で構築するSplunkのアーキテクチャが本番環境で耐え得るのかどうかについて考察します。また、本番環境を構築するに当たっての検討すべきポイントについても併せて解説するので、ぜひ楽しみにしていてください。
株式会社リクルート リスクマネジメント担当 セキュリティ推進室 セキュリティオペレーションセンター ソリューションアーキテクトグループ 兼 インシデントレスポンスグループ所属。
5年間、SIerに在籍。インフラエンジニアとして、主にサーバやセキュリティアプライアンスの設計や構築を担当。2018年から現職において、Splunk基盤の運用や次期ログ分析基盤の検証を担当。現在はインシデントレスポンスグループで攻撃者の思考回路をトレースしながら、どんな悪いことができるのか日々勉強中。BigQueryやSplunkなどを用いたログ分析に情熱を注いでいる。
Copyright © ITmedia, Inc. All Rights Reserved.