【AWS マルチアカウント】 あのサービスなしでログ集約とイベント検知の仕組みを整備

カバー

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

前回に引き続き、AWS Organizations と AWS CloudFormation を使用しない AWS のマルチアカウント管理について、設定や実装アプローチを紹介します。今回は、「操作ログの集約」と「イベント発生の検知と通知」にフォーカスします。

操作ログの集約

前回の記事、【AWS マルチアカウント】 あのサービスなしでログインの仕組みを整備では、スイッチロールを活用したログイン管理の仕組みについて紹介しました。しかし、利用者がログインした後に「利用者の操作が見えない」状態です。もちろん、管理部門の人間が各アカウントにログインして確認することはできますが、各プロジェクトアカウントの AWS リソースをすべて確認するというのは現実的ではありません。そこで、各アカウントのログやイベントの集約管理とその設定を行う「セキュリティアカウント」を作成し、「利用者の操作」を一ヵ所から確認できるようにしました。

集めたログは AWS CloudTrail, AWS Config, Amazon GuardDuty が記録するログで、すべてセキュリティアカウントで作成した Amazon S3 バケットにログを保存するように設定しました。どのサービスについても、サービスの機能で異なるアカウントの Amazon S3 バケットへログを保存できるため、特に複雑な設定や操作は必要ありません。しかし、グローバルサービスの扱いについては注意が必要です。

グローバルサービスに関する記録

グローバルサービスとは、その名の通りリージョンに縛られないサービスです。AWS IAM などが該当し、ログインやスイッチロールもグローバルサービスのログとして記録されることがあります。グローバルサービスのログは全リージョンで記録されてしまうため、通常の設定では1つのアクションに対する料金が有効化しているリージョンの数だけ発生してしまいます。

AWS CloudTrail と AWS Config は、リージョンごとにグローバルサービスの記録を行うかどうかを設定できます。グローバルサービスの記録を1つのリージョンのみで行うことによって料金の無駄を省くことができます。ただし、CloudTrail の証跡でグローバルサービスの記録を行うかどうかはコンソールから設定できないため、AWS CLI を使用する必要があります。

イベント発生の検知と通知の仕組み

操作ログを集めることで、セキュリティアカウントから全アカウントの使用状況を確認できるようになりましたが、管理部門の人間が「自分からログインして確認しなければならない」というのは変わっていません。インシデントの発生など、イベントが発生したことを即座に把握したい場合は、操作ログを集約するだけでは不十分です。そこで、以下のような構成でイベント発生の検知と通知の仕組みを整備しました。

通知するイベント内容

今回、各サービスで通知するイベント内容として指定したものは、以下の3つです。

  • CloudTrail : セキュリティグループの作成・変更・削除
  • GuardDuty : findings(GuardDuty が検知した脅威の内容を記述したもの)
  • Config : GuardDuty と CloudTrail の有効・無効を判定する Config ルールの状態変化

プロジェクトアカウントでどのように AWS が利用されているかを把握するために、セキュリティグループの作成・変更・削除のすべてについて通知を行っていますが、最終的には、管理側として設定してほしくないルールの追加が行われたときに通知するように改良していく予定です。Config ルールでは、今回のマルチアカウント管理の根幹となる GuardDuty と CloudTrail が無効化されたときに、それを検知するようなマネージドルールを有効化しました。他の Config ルールについても、運用を進めていく中で、随時追加していく予定です。

検知と通知の流れ

当社では、社内ネットワークと VPN 接続した VPC のあるアカウントが1つのみなので、社内チャットへ通知を行う Lambda 関数をセキュリティアカウントにおくことはできません。その代わりに、関数のトリガーとなる Amazon SNS のトピックをセキュリティアカウントで作成することで、関数の呼び出しはセキュリティアカウントから行うようにしました。

検知と通知の流れを簡単にまとめると、以下のようになります。

  1. プロジェクトアカウントの CloudTrail、GuardDuty、Config がイベントの発生を検知
  2. プロジェクトアカウントの Amazon EventBridge のイベントルールで検知したイベントから通知を行うべきイベントを選別し、セキュリティアカウントのイベントルールに共有
  3. セキュリティアカウントのイベントルールのターゲットである SNS から、検知したイベント内容を含んだメッセージを社内ネットワークと VPN 接続した VPC のあるアカウントの Lambda 関数に送信
  4. メッセージの送信をトリガーとして Lambda 関数が起動し、社内チャットへ通知を行う

イベントの検知や選別、アカウント間の共有、EventBridge による Lambda 関数の呼び出しは、リージョンをまたいで行うことはできません。そのため、イベントルールから直接関数を呼び出す構成だと、各リージョンに関数を作成する必要が出てきてしまいます。今回の構成では、SNS を経由させることによってリージョンをまたぐことができるため、通知を行う関数を各リージョンに作成しなくてもよくなりました。

全てのアカウントおよびリージョンに設定を適用する方法

最後に、「全てのアカウントおよびリージョンに、個別に設定を適用するのが大変」という課題に対するアプローチを紹介します。AWS Organizations や AWS CloudFormation を使わずに、マルチアカウント管理の環境を整える際に、おそらく一番の課題となるのはここではないかと思います。各アカウントの全リージョンに対し、手作業で設定を適用させることは困難です。そこで、使用したのが AWS CLI です。

AWS CLI は「サービスを管理するための統合ツールで、コマンドラインから複数の AWS サービスを制御し、スクリプトを使用してこれらを自動化することができる」というものです。しかし、アカウントをまたいで設定をしなければならない場合、アクセスキーやシークレットアクセスキーの取得など、アカウントの切り替えに少々面倒な準備が必要になります。また、プロジェクトアカウントで作業する場合は、そのアカウントで作成した IAM ユーザーの認証情報で AWS CLI コマンドを実行することになります。そのため、前の記事で紹介した AD のユーザーでの AWS 利用ができません。これらの問題を解決するのが、ログイン管理の仕組みにも登場した「スイッチロール」です。

AWS CLI でのスイッチロール

AWS CLI でもスイッチロールできます。スイッチロールでアカウントの切り替えを行う場合、アクセスキーやシークレットアクセスキーの取得をする必要はありません。以下のコマンドを実行することで、AWS CLI でのロール A からロール B へのスイッチロールの設定を行うことができます。

aws configure set role_arn {ロール B の ARN} --profile {プロファイル名}
aws configure set source_profile default --profile {プロファイル名}

これらのコマンドを実行すると、.aws/config ファイルに以下の内容が追加されます。

[profile {プロファイル名}]
role_arn = {ロール B の ARN}
source_profile = default

この状態で、コマンドを実行する際に、profile オプションで「プロファイル名」を指定するとスイッチロールした状態でコマンドが実行されます。また、AWS CLI では、コンソール画面ではできない「スイッチロールした状態からスイッチロールする」ことができます。以下のように、source_profile に別のプロファイル名を指定することで、Jump アカウント(ロール A) → セキュリティアカウント(ロール B) → プロジェクトアカウント(ロール C)のようにスイッチロールが可能です。

[profile security-account]
role_arn = {ロール B の ARN}
source_profile = default

[profile project-account-from-security-account]
role_arn = {ロール C の ARN}
source_profile = security-account

各プロジェクトアカウントに、セキュリティアカウントからのスイッチロールを受け入れるロールを作成しておけば、セキュリティに関するすべての操作をセキュリティアカウントから実行できます。その結果、管理者も AD のユーザーで AWS を利用しつつ、セキュリティアカウントを経由してプロジェクトアカウントの設定ができます。また、ロール C は「セキュリティアカウントからのスイッチロールのみを受け入れる」ようにすることで、管理部門以外はスイッチロールに使用できなくなります。

AWS CLI でのスイッチロールに関する設定はすべて CLI のコマンドから設定できます。スイッチロールを受け入れるためのロールは、プロジェクトアカウントにサインインして作成する必要がありますが、それ以外は、スイッチロールに関する設定も含めてスクリプト内で行うことができます。

スクリプト作成時の注意

アカウントで有効化されていないリージョンで CLI コマンドを実行しようとすると、エラーが発生してしまいます。これは、スクリプトの最初にアカウントで有効化されているリージョンの一覧を取得し、そこでのみ設定を行うことで対策できます。CLI コマンドの aws ec2 describe-regions を実行することで、有効化されているリージョンの一覧を取得できます。

最後に

今回、「操作ログの集約」と「イベント発生の検知と通知」の仕組みと、その実装方法について紹介しました。【AWS マルチアカウント】 あのサービスなしでログインの仕組みを整備で紹介した「ログイン管理」とあわせて、マルチアカウント運用開始時の課題を解決することができました。集めたログを活用する方法など、今回の環境整備で手が回らなかった部分も多々あるため、今後も試行錯誤を重ねて体制を強化していきたいと思っています。この記事が AWS Organizations を利用しないマルチアカウント管理について悩んでいる方の参考になればと思います。最後までお読みいただきありがとうございました。

参考資料


TOP
アルファロゴ 株式会社アルファシステムズは、ITサービス事業を展開しています。このブログでは、技術的な取り組みを紹介しています。X(旧Twitter)で更新通知をしています。