AWSのCloudWatch Logs(以下、CWLogs)に吐き出しているログを、必要な情報だけに絞ってSplunk Cloudへ連携・分析させる構成を実装する機会がありました。
本記事では、その実装手順をステップバイステップで紹介します。
金融・エンタープライズ環境での導入を想定しているため、セキュリティとコストの両面にも触れています。

この記事でわかること

  • CloudWatch Logs → Kinesis Data Firehose → Splunk Cloud への自動転送パイプラインの構築方法
  • HECトークンを Secrets Manager でセキュアに管理する手順
  • サブスクリプションフィルタを使った転送前ログフィルタリング・マスキングの設定方法
  • 各ステップにおけるコスト感とハマりポイント

全体構成

今回の実装は、以下の4ステップで進めます。

1.Step 1  Splunk Cloud の HECエンドポイント・トークンを準備する

2.Step 2  HECトークンを Secrets Manager に格納する

3.Step 3  Amazon Data Firehose を設定する

4.Step 4  CWLogs のサブスクリプションフィルタでフィルタリング・マスキングを設定する

実装

HEC トークンの発行

5.Splunk Web(管理者アカウント)にログインします。

6.画面右上または「設定」メニューから [データ入力] を選択。

7.[HTTP Event Collector] をクリック。

8.右上の [新規トークンの追加] をクリックし、必要なインデックスやソースタイプを指定してトークンを生成します。

9.生成されたトークン値(例:a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6)をコピーして控えておきます。

エンドポイント URL と送信テスト

外部システムからログを送信するエンドポイントURLは以下の形式です。

https://http-inputs-<スタック名>.splunkcloud.com/services/collector

curl コマンドでテスト送信してみましょう。

curl -k https://http-inputs-<スタック名>.splunkcloud.com/services/collector \

    -H “Authorization: Splunk {$HEC_TOKEN}” \

    -H “Content-Type: application/json” \

    -d ‘{“event”: “hogehoge”, “sourcetype”: “json”}’

Splunk 側の画面にテストメッセージが反映されていればOKです。

⚠️ ハマりポイント
Splunk 側の IP Allow List に送信元 IP が登録されていないと、ここで詰まります。筆者もここで小一時間ほど停滞しました(1敗)。テスト前に必ず確認しておきましょう。

Amazon Data Firehose は Secrets Manager に格納されたシークレット値を直接参照できます。Firehose の設定に平文で書くこともできますが、せっかくなので Secrets Manager を使ってセキュアに管理してしまいましょう。

10.AWSコンソール → [Secrets Manager] → [新しいシークレットを保存する] を選択。

11.[シークレットのタイプ] で「その他のシークレットのタイプ」を選択し、[キー/値のペア] を以下のように設定します。   キー:hec_token  値:Step 1 で取得した HEC トークン

12.暗号化キーはマネージドキー(aws/secretsmanager)でOKです(要件に応じて変更)。

13.名前・説明を記入し、タグを必要に応じて付与します。ローテーションは今回対象外のため、以降の設定はスキップでOKです。

Firehose ストリームの作成

14.[Data Firehose] → [Firehose ストリームを作成] をクリック。

15.[ソース]:Direct PUT / [送信先]:Splunk を選択。

16.任意のストリーム名をつけ、[Splunk クラスターエンドポイント] に Step 1 で確認した HEC エンドポイントを入力します。エンドポイントタイプはデフォルトでOK。

「レコードを変換」オプション > Amazon CloudWatch Logs からソースレコードを解凍する にチェックを入れ、ログ転送時に解凍する。

17.[認証] で [AWS Secrets Manager] にチェックを入れ、Step 2 で作成したシークレットを選択します。

18.バックアップ先の S3 を任意で設定します(失敗したログのみを対象にするのがおすすめです)。

Secrets Manager のリソースアクセスポリシーを編集する

このままだとシークレット取得時にエラーで弾かれます。Firehose から GetSecretValue できるよう、リソースアクセスポリシーを編集します。

[Step 2 で作成したシークレット] → [リソースのアクセス許可] → [編集] からポリシーを追加します。

{

  “Version”: “2012-10-17”,

  “Statement”: [

    {

      “Effect”: “Allow”,

      “Principal”: {

        “AWS”: “arn:aws:iam::{AccountID}:role/{Firehoseのサービスロール名}”

      },

      “Action”: “secretsmanager:GetSecretValue”,

      “Resource”: “*”

    }

  ]

}

不用意にじゃばじゃばログを転送してしまうと、データ転送コストがそれなりに嵩んできます。転送前にフィルタリングを行い、必要なログだけを絞り込む設定を行いましょう。

💰 コストの目安(東京リージョン)
CWLogs → Firehose 転送:約 0.055 USD / GB / AWS → Splunk(インターネット経由):別途 約 0.114 USD / GB

ログフィルタリングの設定手順

19.[CloudWatch] → [ロググループ] に移動。

20.対象ロググループを選択し、[サブスクリプションフィルター] タブをクリック。

21.[作成] → [Amazon Data Firehose サブスクリプションフィルタを作成] を選択。

22.Step 3 で作成した Firehose ストリームを送信先に設定し、アクセス用の IAM ロールを作成します(後述)。

23.[ログの形式] で [JSON] を選択し、[サブスクリプションフィルターパターン] に抽出条件を入力します。

24.[パターンのテスト] でフィルタが正しく機能しているか確認。

25.[テストするログデータを選択] → [カスタムログデータ] にテストログを貼り付け、正常に出力されたら [ストリーミングを開始] をクリック。

フィルタパターンの記述例:

# ERRORまたはCRITICALを含むログのみ転送

[w1=”*ERROR*” || w1=”*CRITICAL*”]

# JSONログ内のstatusが500のもののみ転送

{ $.status = 500 }

# STARTやENDが含まれるログを除外

– “START” – “END”

IAM ロール記述例:

// ポリシー

{

    “Version”: “2012-10-17”,

    “Statement”: [{

        “Effect”: “Allow”,

        “Action”: [“firehose:PutRecord”],

        “Resource”: [

            “arn:aws:firehose:{リージョン}:{AccountID}:deliverystream/{ストリーム名}”

        ]

    }]

}

// 信頼関係

{

  “Version”: “2012-10-17”,

  “Statement”: [{

    “Effect”: “Allow”,

    “Principal”: { “Service”: “logs.amazonaws.com” },

    “Action”: “sts:AssumeRole”,

    “Condition”: {

      “StringLike”: {

        “aws:SourceArn”: “arn:aws:logs:{リージョン}:{AccountID}:log-group:{ロググループ}:*”

      }

    }

  }]

}

ログマスキング(データ保護ポリシー)の設定

個人情報や機密情報が含まれるログをそのまま転送したくない場面では、CWLogs のデータ保護ポリシーを使ったマスキングが有効です。

26.対象ロググループを選択し、[データ保護] タブをクリック。

27.[ポリシーの作成] または [編集] をクリック。

28.[データ保護設定] で隠したい情報の種類(例:EmailAddress, IpAddress, AwsSecretKey など)を選択。

29.正規表現など独自ルールが必要な場合は [カスタムデータ識別子の設定] で追加。

30.監査先を [Amazon Data Firehose] に設定し、[データ保護をアクティブ] をクリックして完了。

設定が完了すると、選択した機密情報が自動的に [***_CONFIDENTIAL_***] に置換された状態で Splunk へ転送されるようになります。

⚠️ 追加コストに注意
データ保護ポリシーによるマスキングを有効にした場合、CWLogs 側でスキャンされたデータに対して 0.12 USD / GB の追加料金が発生します。

まとめ

本記事では、CWLogs のログを Splunk へ安全に転送するパイプラインを4ステップで構築する方法を紹介しました。各ポイントを振り返ります。

  • HECトークンは Secrets Manager で管理することで、設定ファイルへの平文記述を避けられる
  • サブスクリプションフィルタを使ったフィルタリングにより、Splunk 側のインジェストコストを最適化できる
  • データ保護ポリシーのマスキングで、機密情報を転送前に安全に除去できる
  • Firehose の S3 バックアップを組み合わせることで、金融機関水準のログ管理体制を実現できる

同様の課題をお持ちの方のお役に立てれば幸いです。