SQS-Based S3でAWSのログをSplunkに取り込む

2024.03.02

SplunkでAWSのログ集約をしてみたいと思います。
他の方もSplunkへのAWSログ集約に関するブログを書かれていたりするとは思うのですが、AWSへのログの送信方法はいくつものパターンがあるので自分の整理も兼ねて確認していきたいと思います。

AWSログ送信アーキテクチャ

AWSでは、サードパーティーへのデータ連携の方法として主に二つのパターンがサポートされています。
Push型とPull型ですね。

Splunkの場合も同様に大きく分けるとこの2つの方法になります。

Push型

Kinesis Data Firehoseを使って、ログをPush型でリアルタイムに送信していくアーキテクチャです。
このアーキテクチャを採用する時のメリットは以下になります。

  • データレイテンシが少なく、大量のデータを高速でリアルタイムに配信することができる
  • データスループットの変動に伸縮可能に対応することができる
  • データ転送失敗時のリトライ機能

データ転送に対して信頼性が高く、リアルタイム性に優れた連携方法になるのでデータの転送量が多い場合に特に適したアーキテクチャになります。
一方、Pull型より転送コストが高くなる傾向にあります。

Pull型

代表的なアーキテクチャは S3バケット - SQS - SNS を連携させ、信頼性と即時性の高いデータ収集を行います。
このアーキテクチャを採用する時のメリットは以下になります。

  • データ収集失敗時はSQSによる非同期処理によってリカバリー
  • VPCエンドポイント経由でのプライベートでのデータ連携が可能
  • Push型に比べて比較的コスト低

即時性、信頼性ともにPush型ほどではないですが、メッセージキューイングサービスとの連携により、十分なメリットが高いアーキテクチャになります。

公式サイトのAWS統合のアーキテクチャに関するドキュメントになります。

Splunk Add on for AWS

Splunk Add on for AWS は AWS環境のログ統合を行うための、Splunk Appになります。
データソースやCIM(Common Information Model)の定義を行ってくれたり、データ送信設定をサポートしてくれる機能があります。

先程の公式サイトのAWS統合アーキテクチャのドキュメントでは、Splunk Add on for AWSはPull型のみに対応していると書かれているのですが、Splunk Add on for AWSのドキュメントにはPush型の設定方法についても記載されているので、おそらく設定できるものかと思います。

今回はまずPull型で設定を進めていきます。
また、SplunkのプラットフォームはSplunk CloudのTrialを使っていきます。

CloudTrailログの収集

今回、CloudTrailログの収集をPull型でやってみます。
Pull型でもさらにいくつかの収集方法がありますが、Splunk Add on for AWSでも推奨となっているSQS-Based S3を行います。
先程のアーキテクチャのPull型で紹介したものと同等なものなります。

CloudTrailの設定(SNS作成)

CloudTrailのイベント発生時にSNSサブスクリプションを発行するように設定します。
SNSの作成はCloudTrailの設定から行うと、ポリシーの設定が簡単になるので、CloudTrailで追加します。
CloudTrailの証跡でSNS通知の配信を有効化して、SNSを作成します。

SQSの設定

次にSQSを2つ作ります(1つはデッドレターキュー)。

まず最初にデッドレターキューから作ります。
名前を入れたら、アクセスポリシーの設定等含めてデフォルト値でつくります。

もう一つキューを作ります。

こちらは、設定を編集して、可視性タイムアウト5分にします。
後で、SplunkのINPUTの設定で、5分以上にしておかないと設定ができないようです。

さらにアクセスポリシーを編集します。

{
  "Version": "2012-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__sender_statement",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "SQS:SendMessage",
      "Resource": "<arn:aws:sqs:ap-northeast-1:000000000000:this-sqs-queue>",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "<arn:aws:sns:ap-northeast-1:000000000000:your-sns-topic>"
        }
      }
    }
  ]
}

さらに、デッドレターキューを指定します。

SNSの設定

CloudTrailの設定の時に、SNSが出来ているので、サブスクリプションの作成で先程作ったSQSを指定します。

IAMポリシーの作成(ロール用)

ロール用のポリシーを作成します。
ここでは、splunk-cloudtrail-role-policyとしました。
対象リソースは作ったSQSのARN、CloudTrailイベントが格納されているS3バケットのARNを指定します。
(※ポリシー設定では<arn:aws:s3:::your-cloudtrails3-bucket>/*を忘れないでください。)
最小権限で設定しています。
ドキュメントはこちらが参照先になると思いますが、設定してみたら足りなかったのでいくつか権限を足しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "sqs:ListQueues",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "sqs:GetQueueUrl",
                "sqs:ReceiveMessage",
                "sqs:SendMessage",
                "sqs:DeleteMessage",
                "sqs:ChangeMessageVisibility",
                "sqs:GetQueueAttributes",
                "s3:ListBucket",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketLocation",
                "kms:Decrypt"
            ],
            "Resource": [
                "<arn:aws:sqs:ap-northeast-1:000000000000:your-sqs-queue>",
                "<arn:aws:s3:::your-cloudtrails3-bucket>",
                "<arn:aws:s3:::your-cloudtrails3-bucket>/*"
            ]
        }
    ]
}

IAMポリシーの作成(Splunkユーザー用)

Splunk Cloudが外部からアクセスしてくるためのポリシーを作成します。
ここでは、splunk-user-policyという名前で作りました。
リソースには、次の手順で設定するロール名を指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "<arn:aws:iam::000000000000:role/your-iam-role>"
        }
    ]
}

IAMユーザーの作成(Splunkユーザー用)

コンソールログインは提供しないにして、APIキーを発行します。
ここではsplunk-userという名前で作成します。
Splunkユーザー用に作ったポリシー(例:splunk-user-policy)をアタッチします。

S3、SQSにアクセスするためのIAMロールの作成

AssumeRoleを引き受けるためのロールを作成します。
ロール用に作成したポリシー(例:splunk-cloudtrail-role-policy)をアタッチして。信頼関係の設定で、作成したユーザー(例:splunk-user)を指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::000000000000:user/<your-iam-user>"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Splunk CloudでAWSアカウントの登録

Splunk CloudのSplunk Add-on for AWSで、AWSアカウント情報とアクセスするユーザー情報を登録します。

AWSで作成したIAMユーザーのアクセスキーなどを設定します。
名前は任意で大丈夫です。

IAMロールの登録

つづいてSplunk CloudでIAMロールを登録します。

こちらも名前は任意で大丈夫です。
先ほど作成したAWSのIAMロールのARNを設定します。

Inputsの設定

次にInputsでCloudTrailのSQS-Based S3を選択します。

基本的に上から順番に選択していくと、先程登録した内容にしたがって、自動で選択肢として選ぶことができるようになりますので進んでいくだけです。

データの確認

Search画面を使って、ログが取り込まれていることを確認します。
CloudTrailのソースタイプは、「aws:cloudtrail」になっているのでsourcetype="aws:cloudtrail"で検索してみます。

5分程度待っても何も出力されない場合は、トラブルシューティングが必要です。
Searchコマンドでindex=_internalで内部ログを見ていきます。

index=_internal source="*cloudtrail*"

sourceなども指定し、ログを絞って直近の内部ログを見てみます。
下記のようなエラーが出ているので、確認していきます。(ポリシーの権限が足りていないので、Roleにアタッチしていたポリシーを追加していきました。)

下記のような感じで期待するCloudTrailのイベントが取れてくればOKです。

まとめ

AWSのログをSplunkに取り込む時の一番スタンダードな方法かと思いますので、このアーキテクチャを応用して他のデータも取っていけばよさそうです。
次回はKinesis Data Firehoseを使ったPush型も試してみようと思います。