SIEM on Amazon OpenSearch Service のデプロイ時に作成される 43 リソースをぜんぶ図に書き起こしてみた

SIEM on Amazon OpenSearch Service を完全に理解しましょう。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。


SIEM on Amazon OpenSearch Service の全体像って結局どうなってるの……?


コンバンハ、千葉(幸)です。

SIEM on Amazon OpenSearch Service は、セキュリティインシデントを調査するためのソリューションです。かつては SIEM on Amazon ElasticSearch Service という名称でしたが、やんごとなき理由から名称が変更されました。

ソリューションは一式まとめて CloudFormation テンプレートとして用意されており、それをデプロイするだけで最低限の環境は整います。

CloudFormation テンプレートで定義されているリソースは思いのほか多く、数えてみると 43 個ありました。一度に 3 個までしか頭に思い浮かべられないわたしは理解に苦労したので、全体を把握するために絵を描いてみることにしました。

先にチラ見せするとこんな感じです。後でちゃんとフルサイズのものが出てきます。

SIEM on Amazon OpenSearch Service とは

改めて SIEM on Amazon OpenSearch Service とは何かを取り上げたいと思いましたが、その詳細は以下に譲ります。

2020 年 10 月に SIEM on Amazon ElasticSearch Service として発表され、当時に詳しくその説明が行われています。

当時と比較し、細かい部分の名称が変わった以外は全体のアーキテクチャも作成されるリソースも変更はありません。よって、改めて語ることはそこまでありません。いろんなサービスのログを……いい感じにビジュアライズできるソリューションなんだな、と思ってください。

いくつか SIEM on Amazon ES として取り上げているエントリがありますので、合わせてご参照ください。

確認に使用する CloudFormation テンプレート

2021 年 9 月 21 日時点で最新であった以下の CloudFormation テンプレートを使用します。

CloudFormation コンソールへのリンクなども提供されておりますので、デプロイ方法の詳細は以下の README _ja.md を参照ください。

アーキテクチャ図もここで提供されています。理解に必要な分だけ抽出して載せられていますが、一度全量を見てみたいと思うのが人のサガというものです。そこのモチベーションが今回のすべてです。

siem-architecture

SIEM on Amazon OpenSearch Service をデプロイした

手順に則り CloudFormation テンプレートをデプロイし、リソースが作成された状態からスタートします。

CloudFormation スタックからテンプレートを確認できるので、そこからデザイナーで表示をしてみます。

CloudFormation_-_stack_siem

デザイナーで表示されたイメージをエクスポートしたものが以下です。

そうですね、こう…… ……

43 個あるな、っていうのがよく分かっていいですね。

デザイナー上で各リソースは自由に位置を変えられるので、そこで整理して見やすくできないかなと思いチャレンジしましたが、180 秒ほどで頓挫しました。

こうやって絵で見ると、KMS のエイリアスや Lambda 関数のリソースベースポリシー、SNS のサブスクリプションなど、普段独立したリソースとして考えないものを意識する機会になっていいですね。

SIEM on Amazon OpenSearch Service のリソース一覧

同じく CloudFormation スタックのリソース一覧から詳細を確認してみます。

(ここまで当たり前のように「リソース」と言ってきましたが、本エントリではあくまで CloudFormation におけるリソースのことを指しています。例えば S3 バケットポリシーは CloudFormation ではリソースの一つですが、一般的には「リソース」と呼ばないと思います。わたしの中では、 ARN を持つかどうかがリソースか否かの基準です。余談でした。)

CloudFormation_-_stack_siem_resource

ここでは(テンプレートでの記載順でなく)論理 ID でアルファベット順にソートされて表示されています。関係性の強いリソースがまとまっている傾向はありますが、必ずしもそういうわけではないため読み解くにはちょっと苦労しました。

勝手に番号を振った表を載せます。いくつか補足があります。

  • わかりやすさのためリソースタイプの列を前に持ってきています
  • 物理 ID は自動採番される部分もそのまま記載しているので、環境によって完全に一致しない部分もあります
  • ACCOUNTNUMBERとしている箇所は 12桁 の AWS アカウント番号を表します
| #  | リソースタイプ                          | 論理ID                                                                                      | 物理ID                                                                                               |
|----|-------------------------------------|---------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|
| 1  | AWS::IAM::Role                      | AesSiemDeployRoleForLambda654D64F2                                                          | aes-siem-deploy-role-for-lambda                                                                     |
| 2  | AWS::SQS::Queue                     | AesSiemDlq1CD8439D                                                                          | https://sqs.ap-northeast-1.amazonaws.com/ACCOUNTNUMBER/aes-siem-dlq                                 |
| 3  | AWS::CloudFormation::CustomResource | AesSiemDomainConfiguredR2                                                                   | aes-siem-config-2.5.0-OUIOCBHC                                                                      |
| 4  | AWS::CloudFormation::CustomResource | AesSiemDomainDeployedR2                                                                     | aes-siem-domain-2.5.0-JEXBJSSY                                                                      |
| 5  | AWS::IAM::InstanceProfile           | AesSiemEsLoaderEC2InstanceProfile                                                           | aes-siem-es-loader-for-ec2                                                                          |
| 6  | AWS::IAM::Policy                    | AesSiemEsLoaderEC2RoleDefaultPolicyAF44001A                                                 | siem-AesSi-1JXZBK7M49UUF                                                                            |
| 7  | AWS::IAM::Role                      | AesSiemEsLoaderEC2RoleFE3F9F00                                                              | aes-siem-es-loader-for-ec2                                                                          |
| 8  | AWS::IAM::Role                      | AesSiemSnapshotRoleF313ED39                                                                 | aes-siem-snapshot-role                                                                              |
| 9  | AWS::IAM::Role                      | AesSiemSnsRole64262F46                                                                      | aes-siem-sns-role                                                                                   |
| 10 | AWS::IAM::Policy                    | AesSiemSnsRoleDefaultPolicy7B8095B5                                                         | siem-AesSi-17L60ZVQ5HETN                                                                            |
| 11 | AWS::SQS::Queue                     | AesSiemSqsSplitLogs0191F431                                                                 | https://sqs.ap-northeast-1.amazonaws.com/ACCOUNTNUMBER/aes-siem-sqs-splitted-logs                   |
| 12 | AWS::Lambda::Function               | BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691                          | siem-BucketNotificationsHandler050a0587b7544547bf3-4mQJQjN4GWYN                                     |
| 13 | AWS::IAM::Role                      | BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC                      | siem-BucketNotificationsHandler050a0587b7544547bf3-10EXM86PQSK4O                                    |
| 14 | AWS::IAM::Policy                    | BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36         | siem-Bucke-1G79XCBY75ZYQ                                                                            |
| 15 | AWS::Lambda::Permission             | CwlRuleLambdaGeoipDownloaderDillyAllowEventRuleaessiemLambdaGeoipDownloaderC2D21D0094BEB6E6 | siem-CwlRuleLambdaGeoipDownloaderDillyAllowEventRuleaessiemLambdaGeoipDownloaderC2D21D-MEPXYLADTQBL |
| 16 | AWS::Events::Rule                   | CwlRuleLambdaGeoipDownloaderDillyF68D857D                                                   | siem-CwlRuleLambdaGeoipDownloaderDillyF68D857D-QHMS2DGWILWX                                         |
| 17 | AWS::CloudFormation::CustomResource | ExecLambdaGeoipDownloader                                                                   | geoipdb                                                                                             |
| 18 | AWS::KMS::Key                       | KmsAesSiemLog44B26597                                                                       | 63328308-0c78-45e9-b127-dcf39048c40a                                                                |
| 19 | AWS::KMS::Alias                     | KmsAesSiemLogAliasE0A4C571                                                                  | alias/aes-siem-key                                                                                  |
| 20 | AWS::Lambda::Function               | LambdaConfigureAESA0471961                                                                  | aes-siem-configure-aes                                                                              |
| 21 | AWS::Lambda::Version                | LambdaConfigureAESVersion250C9F3A6F3                                                        | arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-configure-aes:3                       |
| 22 | AWS::Lambda::Function               | LambdaDeployAES636B5079                                                                     | aes-siem-deploy-aes                                                                                 |
| 23 | AWS::Lambda::Version                | LambdaDeployAESVersion250A9965F7E                                                           | arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-deploy-aes:3                          |
| 24 | AWS::Lambda::Function               | LambdaEsLoader4B1E2DD9                                                                      | aes-siem-es-loader                                                                                  |
| 25 | AWS::IAM::Policy                    | LambdaEsLoaderServiceRoleDefaultPolicyB7A386B3                                              | siem-Lambd-16HNQZMTUL5FV                                                                            |
| 26 | AWS::IAM::Role                      | LambdaEsLoaderServiceRoleFFD43869                                                           | siem-LambdaEsLoaderServiceRoleFFD43869-1EB3R84G12WA5                                                |
| 27 | AWS::Lambda::EventSourceMapping     | LambdaEsLoaderSqsEventSourceaessiemAesSiemSqsSplitLogs506AFFA6A7D8B2E9                      | 51bbc000-c504-4dce-b225-600fee421687                                                                |
| 28 | AWS::Lambda::Version                | LambdaEsLoaderVersion25050D964B0                                                            | arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-es-loader:3                           |
| 29 | AWS::Lambda::Function               | LambdaGeoipDownloaderA5EFF97E                                                               | aes-siem-geoip-downloader                                                                           |
| 30 | AWS::IAM::Policy                    | LambdaGeoipDownloaderServiceRoleDefaultPolicyE7B8AE65                                       | siem-Lambd-YPRZ3L4Y222H                                                                             |
| 31 | AWS::IAM::Role                      | LambdaGeoipDownloaderServiceRoleE37FB908                                                    | siem-LambdaGeoipDownloaderServiceRoleE37FB908-14WK0ONHR051D                                         |
| 32 | AWS::Lambda::Version                | LambdaGeoipDownloaderVersion2509E2AF2E9                                                     | arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-geoip-downloader:3                    |
| 33 | AWS::S3::Bucket                     | S3BucketForGeoip04B5F171                                                                    | aes-siem-ACCOUNTNUMBER-geo                                                                          |
| 34 | AWS::S3::BucketPolicy               | S3BucketForGeoipPolicy854C0CB1                                                              | siem-S3BucketForGeoipPolicy854C0CB1-1T8AVX36PHOR                                                    |
| 35 | AWS::S3::Bucket                     | S3BucketForLog20898FE4                                                                      | aes-siem-ACCOUNTNUMBER-log                                                                          |
| 36 | AWS::Lambda::Permission             | S3BucketForLogAllowBucketNotificationsToaessiemLambdaEsLoaderEBF3B9FB7766EAA3               | siem-S3BucketForLogAllowBucketNotificationsToaessiemLambdaEsLoaderEBF3B9FB7766EAA3-HSUQ91ZY7H1F     |
| 37 | Custom::S3BucketNotifications       | S3BucketForLogNotificationsAEE88E1E                                                         | S3BucketForLogNotificationsAEE88E1E                                                                 |
| 38 | AWS::S3::BucketPolicy               | S3BucketForLogPolicy546D5712                                                                | siem-S3BucketForLogPolicy546D5712-17W2L7QC23HBO                                                     |
| 39 | AWS::S3::Bucket                     | S3BucketForSnapshot40E67D36                                                                 | aes-siem-ACCOUNTNUMBER-snapshot                                                                     |
| 40 | AWS::S3::BucketPolicy               | S3BucketForSnapshotPolicy3DEBD2C0                                                           | siem-S3BucketForSnapshotPolicy3DEBD2C0-1ARXV5WZXIA2Z                                                |
| 41 | AWS::SNS::Topic                     | SnsTopic2C1570A4                                                                            | arn:aws:sns:ap-northeast-1:ACCOUNTNUMBER:aes-siem-alert                                             |
| 42 | AWS::SNS::Subscription              | SnsTopicTokenSubscription1D5A46B4F                                                          | arn:aws:sns:ap-northeast-1:ACCOUNTNUMBER:aes-siem-alert:c2dc4eac-1af8-4ba0-bbe3-15be9c9f3423        |
| 43 | AWS::IAM::Policy                    | aessiempolicytoloadentriestoesE6506021                                                      | siem-aessi-11OOXH4G85OF7                                                                            |

表をそのまま載せると見づらかったので上記のようにシンタックスハイライトの形式で載せました。スプレッドシートなどに転記したい、という場合は以下の csv からどうぞ。

折り畳み
#,リソースタイプ,論理ID,物理ID
1,AWS::IAM::Role,AesSiemDeployRoleForLambda654D64F2,aes-siem-deploy-role-for-lambda
2,AWS::SQS::Queue,AesSiemDlq1CD8439D,https://sqs.ap-northeast-1.amazonaws.com/ACCOUNTNUMBER/aes-siem-dlq
3,AWS::CloudFormation::CustomResource,AesSiemDomainConfiguredR2,aes-siem-config-2.5.0-OUIOCBHC
4,AWS::CloudFormation::CustomResource,AesSiemDomainDeployedR2,aes-siem-domain-2.5.0-JEXBJSSY
5,AWS::IAM::InstanceProfile,AesSiemEsLoaderEC2InstanceProfile,aes-siem-es-loader-for-ec2
6,AWS::IAM::Policy,AesSiemEsLoaderEC2RoleDefaultPolicyAF44001A,siem-AesSi-1JXZBK7M49UUF
7,AWS::IAM::Role,AesSiemEsLoaderEC2RoleFE3F9F00,aes-siem-es-loader-for-ec2
8,AWS::IAM::Role,AesSiemSnapshotRoleF313ED39,aes-siem-snapshot-role
9,AWS::IAM::Role,AesSiemSnsRole64262F46,aes-siem-sns-role
10,AWS::IAM::Policy,AesSiemSnsRoleDefaultPolicy7B8095B5,siem-AesSi-17L60ZVQ5HETN
11,AWS::SQS::Queue,AesSiemSqsSplitLogs0191F431,https://sqs.ap-northeast-1.amazonaws.com/ACCOUNTNUMBER/aes-siem-sqs-splitted-logs
12,AWS::Lambda::Function,BucketNotificationsHandler050a0587b7544547bf325f094a3db8347ECC3691,siem-BucketNotificationsHandler050a0587b7544547bf3-4mQJQjN4GWYN
13,AWS::IAM::Role,BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleB6FB88EC,siem-BucketNotificationsHandler050a0587b7544547bf3-10EXM86PQSK4O
14,AWS::IAM::Policy,BucketNotificationsHandler050a0587b7544547bf325f094a3db834RoleDefaultPolicy2CF63D36,siem-Bucke-1G79XCBY75ZYQ
15,AWS::Lambda::Permission,CwlRuleLambdaGeoipDownloaderDillyAllowEventRuleaessiemLambdaGeoipDownloaderC2D21D0094BEB6E6,siem-CwlRuleLambdaGeoipDownloaderDillyAllowEventRuleaessiemLambdaGeoipDownloaderC2D21D-MEPXYLADTQBL
16,AWS::Events::Rule,CwlRuleLambdaGeoipDownloaderDillyF68D857D,siem-CwlRuleLambdaGeoipDownloaderDillyF68D857D-QHMS2DGWILWX
17,AWS::CloudFormation::CustomResource,ExecLambdaGeoipDownloader,geoipdb
18,AWS::KMS::Key,KmsAesSiemLog44B26597,63328308-0c78-45e9-b127-dcf39048c40a
19,AWS::KMS::Alias,KmsAesSiemLogAliasE0A4C571,alias/aes-siem-key
20,AWS::Lambda::Function,LambdaConfigureAESA0471961,aes-siem-configure-aes
21,AWS::Lambda::Version,LambdaConfigureAESVersion250C9F3A6F3,arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-configure-aes:3
22,AWS::Lambda::Function,LambdaDeployAES636B5079,aes-siem-deploy-aes
23,AWS::Lambda::Version,LambdaDeployAESVersion250A9965F7E,arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-deploy-aes:3
24,AWS::Lambda::Function,LambdaEsLoader4B1E2DD9,aes-siem-es-loader
25,AWS::IAM::Policy,LambdaEsLoaderServiceRoleDefaultPolicyB7A386B3,siem-Lambd-16HNQZMTUL5FV
26,AWS::IAM::Role,LambdaEsLoaderServiceRoleFFD43869,siem-LambdaEsLoaderServiceRoleFFD43869-1EB3R84G12WA5
27,AWS::Lambda::EventSourceMapping,LambdaEsLoaderSqsEventSourceaessiemAesSiemSqsSplitLogs506AFFA6A7D8B2E9,51bbc000-c504-4dce-b225-600fee421687
28,AWS::Lambda::Version,LambdaEsLoaderVersion25050D964B0,arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-es-loader:3
29,AWS::Lambda::Function,LambdaGeoipDownloaderA5EFF97E,aes-siem-geoip-downloader
30,AWS::IAM::Policy,LambdaGeoipDownloaderServiceRoleDefaultPolicyE7B8AE65,siem-Lambd-YPRZ3L4Y222H
31,AWS::IAM::Role,LambdaGeoipDownloaderServiceRoleE37FB908,siem-LambdaGeoipDownloaderServiceRoleE37FB908-14WK0ONHR051D
32,AWS::Lambda::Version,LambdaGeoipDownloaderVersion2509E2AF2E9,arn:aws:lambda:ap-northeast-1:ACCOUNTNUMBER:function:aes-siem-geoip-downloader:3
33,AWS::S3::Bucket,S3BucketForGeoip04B5F171,aes-siem-ACCOUNTNUMBER-geo
34,AWS::S3::BucketPolicy,S3BucketForGeoipPolicy854C0CB1,siem-S3BucketForGeoipPolicy854C0CB1-1T8AVX36PHOR
35,AWS::S3::Bucket,S3BucketForLog20898FE4,aes-siem-ACCOUNTNUMBER-log
36,AWS::Lambda::Permission,S3BucketForLogAllowBucketNotificationsToaessiemLambdaEsLoaderEBF3B9FB7766EAA3,siem-S3BucketForLogAllowBucketNotificationsToaessiemLambdaEsLoaderEBF3B9FB7766EAA3-HSUQ91ZY7H1F
37,Custom::S3BucketNotifications,S3BucketForLogNotificationsAEE88E1E,S3BucketForLogNotificationsAEE88E1E
38,AWS::S3::BucketPolicy,S3BucketForLogPolicy546D5712,siem-S3BucketForLogPolicy546D5712-17W2L7QC23HBO
39,AWS::S3::Bucket,S3BucketForSnapshot40E67D36,aes-siem-ACCOUNTNUMBER-snapshot
40,AWS::S3::BucketPolicy,S3BucketForSnapshotPolicy3DEBD2C0,siem-S3BucketForSnapshotPolicy3DEBD2C0-1ARXV5WZXIA2Z
41,AWS::SNS::Topic,SnsTopic2C1570A4,arn:aws:sns:ap-northeast-1:ACCOUNTNUMBER:aes-siem-alert
42,AWS::SNS::Subscription,SnsTopicTokenSubscription1D5A46B4F,arn:aws:sns:ap-northeast-1:ACCOUNTNUMBER:aes-siem-alert:c2dc4eac-1af8-4ba0-bbe3-15be9c9f3423
43,AWS::IAM::Policy,aessiempolicytoloadentriestoesE6506021,siem-aessi-11OOXH4G85OF7

一覧を眺めると、カスタムリソースが数個含まれていることに気づきます。今回のテンプレートではいずれも Lambda 関数が呼び出されています。

公式情報としてのリソース一覧

一通り書いてから気づいたのですが、README_ja.md にも作成されるリソース一覧がきちんと記載されていました。

必要十分なものに絞って簡潔に分かりやすく記載されている様子に惚れ惚れしますが、今回のテーマは「泥臭く全部やる」なので、その、ごめんなさい。

AWS Resource Resource Name 目的
OpenSearch Service 1.0 or Elasticsearch 7.X aes-siem SIEM 本体
S3 bucket aes-siem-[AWS_Account]-log ログを集約するため
S3 bucket aes-siem-[AWS_Account]-snapshot OpenSearch Service の手動スナップショット取得
S3 bucket aes-siem-[AWS_Account]-geo ダウンロードした GeoIP を保存
Lambda function aes-siem-es-loader ログを正規化し OpenSearch Service へロード
Lambda function aes-siem-deploy-aes OpenSearch Service のドメイン作成
Lambda function aes-siem-configure-aes OpenSearch Service の設定
Lambda function aes-siem-geoip-downloader GeoIP のダウンロード
Lambda function aes-siem-BucketNotificationsHandler ログ用 S3 バケットのイベント通知を設定
AWS Key Management Service (AWS KMS) CMK & Alias aes-siem-key ログの暗号化に使用
Amazon SQS Queue aes-siem-sqs-splitted-logs 処理するログ行数が多い時は分割。それを管理するキュー
Amazon SQS Queue aes-siem-dlq OpenSearch Service のログ取り込み失敗用 Dead Ltter Queue
CloudWatch Events aes-siem-CwlRuleLambdaGeoipDownloader aes-siem-geoip-downloader を12時間毎に実行
Amazon SNS Topic aes-siem-alert OpenSearch Service の Alerting の Destinations で選択
Amazon SNS Subscription inputd email Alert の送信先メールアドレス

SIEM on Amazon OpenSearch Service のリソース一覧全部盛り構成図

というわけで今回の本題である図が、以下です。

せっかくなのでもう一度載せておきます。理由は、「頑張って書いたのに一回だけだと勿体ないから」です。

そのままだと小さくて見づらいと思うので、別タブで開くなどして見てください。

各リソースに振ってある番号は先述の表の番号に対応します。何かしら処理の順番を表すものではありませんのでご留意ください。

図を踏まえての SIEM on Amazon OpenSearch Service の補足

初回のデプロイ用のリソースや、各種 IAM ロール、ポリシーを除外して考えると、公式のアーキテクチャ図でほぼ充足していますね。

siem-architecture

いくつか補足しておきます。

GeoIP 用の Lambda 関数、S3 バケット

README_ja.md を確認すると以下の記載があります。

IP アドレスに国情報や緯度・経度のロケーション情報を付与することができます。ロケーション情報は MaxMind 社の GeoLite2 Free をダウンロードして活用します。ロケーション情報を付与したい方は MaxMind にて無料ライセンスを取得してください。

S3 バケットaes-siem-ACCOUNTNUMBER-geo(#33)を確認すると.mmdb拡張子を持つファイルが格納されているのが分かります。

$ aws s3 ls aes-siem-ACCOUNTNUMBER-geo --recursive
2021-09-23 01:16:30    7458014 GeoLite2/GeoLite2-ASN.mmdb
2021-09-23 01:16:22   73906864 GeoLite2/GeoLite2-City.mmdb
2021-09-23 01:16:33    6414031 GeoLite2/GeoLite2-Country.mmdb

CloudFormation デプロイ時にカスタムリソースとして GeoIP ダウンロードの Lambda 関数aes-siem-geoip-downloader(#29)が実行され、S3 バケットに格納されます。以降は Event ルールにより 12 時間ごとに Lambda 関数が呼び出され定期的にダウンロードが行われます。(CloudFormation スタック実行時のパラメータとしてライセンスキーの入力が必要 )

格納された情報はログの ETL 処理等を行う Lambda 関数aes-siem-es-loader (#24)により利用されます。

Lambda 関数 aes-siem-es-loader

SIEM on Amazon OpenSearch Service で中心的な働きをしている関数です。この関数のトリガーは以下のように設定されています。

aes-siem-es-loader_-_Lambda

S3 バケットaes-siem-ACCOUNTNUMBER-log(#35)のプレフィックスAWSLogs/もしくはUserLogs/にログが Put されるとこの関数が呼び出され、ETL 処理等を行なったのちに Amazon OpenSearch Service にログを格納します。

S3 バケット aes-siem-ACCOUNTNUMBER-log

CloudTrail ログや VPC フローログなど、SIEM on Amazon OpenSearch Service に取り込ませたいログはこのバケットに格納します。

出力先を直接この S3 バケットにすることもできますし、Kinesis Firehose を経由させたり、S3 のレプリケーション機能を使用して出力することもできます。

一つ注意点として、このバケットではデフォルト暗号化が有効になっており、キーとしてalias/aes-siem-key(#18,19)が指定されています。

デプロイした段階ではキーポリシーが以下のようになっており、主要なサービスプリンシパルからのアクセスが許可されています。クロスアカウントの場合など、ここで許可されていないプリンシパルからのアクセスが必要な場合は適宜修正する必要があります。

折り畳み
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678910:root"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion",
                "kms:GenerateDataKey",
                "kms:TagResource",
                "kms:UntagResource"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow GuardDuty to use the key",
            "Effect": "Allow",
            "Principal": {
                "Service": "guardduty.amazonaws.com"
            },
            "Action": "kms:GenerateDataKey",
            "Resource": "*"
        },
        {
            "Sid": "Allow VPC Flow Logs to use the key",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow principals in the account to decrypt log files",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678910:root"
            },
            "Action": [
                "kms:DescribeKey",
                "kms:ReEncryptFrom"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow Athena to query s3 objects with this key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678910:root"
            },
            "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:GenerateDataKey*",
                "kms:ReEncrypt*"
            ],
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:CalledVia": "athena.amazonaws.com"
                }
            }
        },
        {
            "Sid": "Allow CloudTrail to describe key",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "kms:DescribeKey",
            "Resource": "*"
        },
        {
            "Sid": "Allow CloudTrail to encrypt logs",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "kms:GenerateDataKey*",
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:012345678910:trail/*"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678910:role/siem-LambdaEsLoaderServiceRoleFFD43869-1EB3R84G12WA5"
            },
            "Action": "kms:Decrypt",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678910:role/aes-siem-es-loader-for-ec2"
            },
            "Action": "kms:Decrypt",
            "Resource": "*"
        }
    ]
}

S3 バケット aes-siem-ACCOUNTNUMBER-snapshot

#39 のバケットです。ソリューション一式のデプロイ後に中身を確認すると以下の 1 ファイルのみ格納されていました。

% aws s3 ls aes-siem-012345678910-snapshot --recursive --human-readable
2021-09-21 00:21:46  364 Bytes saved_objects/global-dashboard-20210920_152144.ndjson.zip

ダウンロードして解凍して中身を確認すると以下のようになっています。

global-dashboard-20210920_152144.ndjson

{"attributes":{"buildNum":36473},"id":"1.0.0-SNAPSHOT","migrationVersion":{"config":"7.9.0"},"references":[],"type":"config","updated_at":"2021-09-20T15:21:44.078Z","version":"WzAsMV0="}
{"exportedCount":1,"missingRefCount":0,"missingReferences":[]}

README_ja.md では以下記載があります。

 注) Global tenant の 設定やダッシュボード等は自動で上書きされるのでご注意ください。アップデート前に使用していた設定ファイルやダッシュボード等は S3 バケットの aes-siem-[AWS_Account]-snapshot/saved_objects/ にバックアップされるので、元の設定にする場合は手動でリストアしてください。

ダッシュボードの設定などのアップデートが行われる前に自動でここに格納してくれるということですかね。

このバケットや IAM ロールを利用した手動スナップショット取得の仕組みの実装例は以下をご参照ください。

IAM ロール aes-siem-es-loader-for-ec2

#5 の IAM ロールは名称から明らかですが、 EC2 インスタンス用です。(#7 としてインスタンスプロファイルが作成されていることからも分かります。)

リソース一式をデプロイしても EC2 インスタンスは登場してこなかったので何に使うんだろう、と不思議に思っていましたが、このロールを使うときには自分で EC2 インスタンスを用意する必要があります。

通常はソリューションのデプロイ時に作成される S3 バケットaes-siem-ACCOUNTNUMBER-log(#35)にログを Put して SIEM に取り込ませていきますが、すでに作成されている S3 バケットを直接ソースにすることもできます。

その場合には自前で EC2 インスタンスを立て、既存の S3 バケットからログを取り込ませる必要があります。そのケースのために IAM ロールだけ用意されているというわけでした。

これは以下エントリを執筆した のんピ 氏に教えてもらいました。「既存S3バケットをSIEM on Amazon ESにインポートするパターン - S3 バケットに保存された過去データの取り込み」部で使用例を確認できます。

おまけ:OpenSeach Service ドメインの確認

作成された OpenSeach Service ドメインの内訳を describe しました。

サービス名は変わっても AWS サービス名前空間はesのままなんだな、やバージョンがOpenSearch_1.0だな、というありきたりな感想を持ちました。

% aws es describe-elasticsearch-domain --domain-name aes-siem --output yaml
DomainStatus:
  ARN: arn:aws:es:ap-northeast-1:012345678910:domain/aes-siem
  AccessPolicies: '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::012345678910:root"},"Action":"es:*","Resource":"arn:aws:es:ap-northeast-1:012345678910:domain/aes-siem/*"},{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"es:*","Resource":"arn:aws:es:ap-northeast-1:012345678910:domain/aes-siem/*","Condition":{"IpAddress":{"aws:SourceIp":["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"]}}}]}'
  AdvancedOptions:
    override_main_response_version: 'false'
    rest.action.multi.allow_explicit_index: 'true'
  AdvancedSecurityOptions:
    Enabled: true
    InternalUserDatabaseEnabled: true
  AutoTuneOptions:
    State: ENABLE_IN_PROGRESS
  CognitoOptions:
    Enabled: false
  Created: true
  Deleted: false
  DomainEndpointOptions:
    CustomEndpointEnabled: false
    EnforceHTTPS: true
    TLSSecurityPolicy: Policy-Min-TLS-1-2-2019-07
  DomainId: 012345678910/aes-siem
  DomainName: aes-siem
  EBSOptions:
    EBSEnabled: true
    VolumeSize: 10
    VolumeType: gp2
  ElasticsearchClusterConfig:
    ColdStorageOptions:
      Enabled: false
    DedicatedMasterEnabled: false
    InstanceCount: 1
    InstanceType: t3.medium.elasticsearch
    WarmEnabled: false
    ZoneAwarenessEnabled: false
  ElasticsearchVersion: OpenSearch_1.0
  EncryptionAtRestOptions:
    Enabled: true
    KmsKeyId: arn:aws:kms:ap-northeast-1:012345678910:key/76338696-62c6-4c8d-9d20-95d4xxxxxxxx
  Endpoint: search-aes-siem-7gz4ocangx5d6cpezff7pmgeq4.ap-northeast-1.es.amazonaws.com
  LogPublishingOptions:
    ES_APPLICATION_LOGS:
      CloudWatchLogsLogGroupArn: arn:aws:logs:ap-northeast-1:012345678910:log-group:/aws/aes/domains/aes-siem/application-logs
      Enabled: true
  NodeToNodeEncryptionOptions:
    Enabled: true
  Processing: false
  ServiceSoftwareOptions:
    AutomatedUpdateDate: '2021-07-08T17:14:34+09:00'
    Cancellable: false
    CurrentVersion: R20210816-P1
    Description: There is no software update available for this domain.
    NewVersion: ''
    OptionalDeployment: false
    UpdateAvailable: false
    UpdateStatus: COMPLETED
  SnapshotOptions:
    AutomatedSnapshotStartHour: 0
  UpgradeProcessing: false

ちなみに保管時のデータの暗号化に使用されているのは AWS マネージドなキーのaws/esです。(#18,19のキーとは関係ありません。)

設定も describe してみましたが、重複する部分があるのと取り立てて面白い内容はなかったので折りたたんでおきます。興味があればどうぞ。

折り畳み
% aws es describe-elasticsearch-domain-config --domain-name aes-siem --output yaml
DomainConfig:
  AccessPolicies:
    Options: '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::012345678910:root"},"Action":"es:*","Resource":"arn:aws:es:ap-northeast-1:012345678910:domain/aes-siem/*"},{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"es:*","Resource":"arn:aws:es:ap-northeast-1:012345678910:domain/aes-siem/*","Condition":{"IpAddress":{"aws:SourceIp":["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"]}}}]}'
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  AdvancedOptions:
    Options:
      override_main_response_version: 'false'
      rest.action.multi.allow_explicit_index: 'true'
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  AdvancedSecurityOptions:
    Options:
      Enabled: true
      InternalUserDatabaseEnabled: true
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:20:39.507000+09:00'
      UpdateVersion: 11
  AutoTuneOptions:
    Options:
      DesiredState: ENABLED
      MaintenanceSchedules: []
      RollbackOnDisable: NO_ROLLBACK
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: ENABLE_IN_PROGRESS
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  CognitoOptions:
    Options:
      Enabled: false
    Status:
      CreationDate: '2021-09-22T12:23:27.724000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-22T12:23:27.724000+09:00'
      UpdateVersion: 11
  DomainEndpointOptions:
    Options:
      CustomEndpointEnabled: false
      EnforceHTTPS: true
      TLSSecurityPolicy: Policy-Min-TLS-1-2-2019-07
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  EBSOptions:
    Options:
      EBSEnabled: true
      VolumeSize: 10
      VolumeType: gp2
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  ElasticsearchClusterConfig:
    Options:
      ColdStorageOptions:
        Enabled: false
      DedicatedMasterEnabled: false
      InstanceCount: 1
      InstanceType: t3.medium.elasticsearch
      WarmEnabled: false
      ZoneAwarenessEnabled: false
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  ElasticsearchVersion:
    Options: OpenSearch_1.0
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  EncryptionAtRestOptions:
    Options:
      Enabled: true
      KmsKeyId: arn:aws:kms:ap-northeast-1:012345678910:key/76338696-62c6-4c8d-9d20-95d4xxxxxxxx
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  LogPublishingOptions:
    Options:
      ES_APPLICATION_LOGS:
        CloudWatchLogsLogGroupArn: arn:aws:logs:ap-northeast-1:012345678910:log-group:/aws/aes/domains/aes-siem/application-logs
        Enabled: true
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  NodeToNodeEncryptionOptions:
    Options:
      Enabled: true
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  SnapshotOptions:
    Options:
      AutomatedSnapshotStartHour: 0
    Status:
      CreationDate: '2021-09-21T00:04:05.834000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-21T00:19:45.312000+09:00'
      UpdateVersion: 6
  VPCOptions:
    Options: {}
    Status:
      CreationDate: '2021-09-22T12:23:27.724000+09:00'
      PendingDeletion: false
      State: Active
      UpdateDate: '2021-09-22T12:23:27.724000+09:00'
      UpdateVersion: 11

わからなかったらぜんぶ図に書けばいいじゃない

SIEM on Amazon OpenSearch Service デプロイ時に作成されるリソースを全部書き起こしてみました。

主要なリソースは限定的なため、全部を理解しなくても利用するには問題ありません。それこそ README_jp.md に記載されているアーキテクチャ図やリソース一覧で十分でしょう。

とは言えわたしは細かいところがつい気になってしまうたちのため、「このリソースなんのために作られてんだ……?」というのが分からなくなっていました。文字だけで追っているとなかなか理解が難しいため、図に書き起こしてようやく自分の中で腹落ちできました。

自分用の側面が強い図ですが、なんらか参考になれば幸いです。

以上、 チバユキ (@batchicchi) がお送りしました。