Amazon Web Services ブログ

マルチアカウント環境での AWS Session Manager ロギングガードレールの実装

オーストリアの著名な銀行グループである Raiffeisen Bank International (RBI) は、マルチアカウントで AWS 環境を利用しています。これにより、製品チームは、集中管理されたセキュリティガードレールの範囲内で、新しい顧客機能を迅速に構築およびテストできます。これらのガードレールの1つでは、組織全体の Amazon Elastic Compute Cloud (Amazon EC2) インスタンスに対して確立されたすべてのセッションを一元的にロギングする必要があります。これにより、RBI のセキュリティチームは、組織全体のユーザーアクティビティの傾向を分析できるだけでなく、脅威検知、インシデント対応、フォレンジック、ログのアーカイブに関して一貫した管理を適用できます。

RBI のエンジニアは、AWS Systems Manager の機能である Session Manager を活用して EC2 インスタンスへのユーザーセッションを開始します。これには、従来の Secure Shell (SSH) セッションを確立するよりもセキュリティ上の利点がいくつかあります。1 つ目は、インスタンスへのアクセスを既存の AWS Identity and Access Management (IAM) のロールとポリシーで管理できることです。さらに、Session Manager では、セキュリティグループやネットワークACLの許可リストへの登録を伴うような、インバウンドのネットワークレベルのアクセスは不要です。最後に、Session Manager はセッションログをキャプチャし、Amazon Simple Storage Service (Amazon S3) バケットまたは Amazon CloudWatch ロググループに書き込みます。ただし、マルチアカウント環境でセッショログを一元化するには、RBI には他にもいくつか注意すべき点がありました。

  • ポート転送または SSH 経由で接続する Session Manager のセッションでは、ロギングは利用できません。これは、SSH はすべてのセッションデータを暗号化し、Session Manager は SSH 接続のトンネルとしてのみ機能するためです。その結果、RBI はすべてのアカウントで「ポート」タイプの セッションドキュメント の使用を停止することを決定しました。
  • セッションドキュメントはセッションロギングのターゲット S3 バケットを定義するため、RBI は ログアーカイブアカウント の専用バケットを指すドキュメントのみを使用してセッションを起動できるようにする必要がありました。
  • Systems Manager はエージェントベースであるため、特定の S3 バケットにログデータを書き込めるかどうかは、 EC2 インスタンスプロファイル に割り当てられた権限に依存します。そのため、RBI のセキュリティは、不正な利用者が EC2 インスタンスに割り当てられたロールを操作してロギングを回避した場合に備える必要がありました。

すべての RBI AWS アカウントは AWS Organizations によって管理されています。RBI のメンバーアカウント管理者は、アカウントの標準化されたベースライン設定とサービスコントロールポリシー (SCP) でセキュリティが強化されていることにより、IAM 権限を自由に管理できます。構文上の制約のため、SCP は上記のセキュリティ要件をすべて予防的に適用できるほど、きめ細かな権限モデルを提供していませんでした。このことを踏まえ、RBI は AWS エンタープライズサポートと協力して、 AWS Step FunctionsAWS LambdaAmazon Simple Notification Service (Amazon SNS) をベースにしたカスタムソリューションを準備することを決定しました。このソリューションでは、実行中のセッションが準拠していない設定になってないかを継続的に監視できます。

ソリューション概要

High-level architecture of the solution

図 1. ソリューションの大まかなアーキテクチャ

EC2 インスタンスへのセッションを確立するには、以下の条件を満たす必要があります。

  • EC2 インスタンスは、SSM エージェントがオペレーティングシステムにプリインストールされているなど、Session Manager のすべての前提条件を満たしている必要があります(RBI の場合、これはセキュリティ強化された「Golden AMI」の一部です)。
  • 定義済みの IAM ポリシーを EC2 インスタンスプロファイルにアタッチする必要があります。このポリシーは、ログアーカイブアカウントにある S3 バケットと、セッションデータの暗号化 に使用される AWS Key Management Service (AWS KMS) キーへのアクセスを許可します。
  • セッションを開始するには、デフォルトの SSM-SessionManagerRunShell セッションドキュメントを使用する必要があります。このドキュメントは、セッション設定ドキュメントを指定せずに AWS Management Console から開始されたすべてのセッションと、AWS CLI コマンドで開始されたセッションに適用されます。

aws ssm start-session --target instance-id

SSM-SessionManagerRunShell ドキュメント自体は SCP によって制限されているため、メンバーアカウント管理者が変更することはできないことに注意してください。

ソリューションの中心となるのは、セッションのライフサイクルを通じて上記のすべての要件が当てはまることを検証する AWS Step Functions ステートマシンです。

AWS Step Functions state machine for continuous session validation

図 2. 継続的なセッションの検証 のための AWS Step Functions ステートマシン

ユーザーが EC2 インスタンスで Session Manager セッションを開始すると、次のことが起こります。

  1. Amazon EventBridge イベントルール がそのイベントを検出し、 AWS Step Functions ワークフローをトリガーします。
  2. ワークフローはイベントを分析し、ユーザーが SSM-SessionManagerRunShell ドキュメントを使用してセッションを確立したかどうかを確認します。もし、SSM-SessionManagerRunShell ドキュメントを使用していない場合はセッションを終了します。
  3. 次に、ステートマシンは継続的なチェックを実行して、EC2 インスタンスにアタッチされたインスタンスプロファイルが改ざんされていないことを検証します。もし、問題がある場合はセッションを終了します。
  4. ユーザーがセッションを終了すると、ワークフローは最終チェックを実行して、セッションログがログアーカイブアカウントの S3 バケットに保存されていることを確認します。これは、攻撃者がすべての予防策をうまく回避できた場合に対する「セーフティネット」のための検出です。
  5. ワークフローのどの段階でも、ステートマシンがセッション違反を検出すると、次のオペレーションシグナルを発行します。
    • CloudWatch カスタムメトリクス
    • メンバーアカウントの SNS トピックへの通知
    • ログアーカイブアカウントの SNS トピックへの通知

メンバーアカウントで終了したセッションの数が事前に定義されたしきい値を超えた場合、CloudWatch アラームがログアーカイブアカウントに追加の SNS 通知を送信し、セキュリティ上の脅威の可能性があることを示します。これらすべてのシグナルを活用して、自動セキュリティ対応を含め、ローカルの SIEM システムとリアルタイムで統合できます。RBI の場合、Session Manager の使用をブロックするために、メンバーアカウントに SCP が一時的に適用されます。

ソリューションウォークスルー

前提条件

ソリューションをデプロイするには、少なくとも 2 つのメンバーアカウントを持つ AWS Organizations アカウントを設定する必要があります。これらのメンバーアカウントのいずれかをログアーカイブアカウントとして指定する必要があります。ログアーカイブアカウントには、S3 バケット、KMS キー、および SNS トピックが格納されます。どちらのアカウントにも、管理者権限を持つ IAM ユーザーまたはロールが必要です。さらに、AWS CloudTrail を設定する必要があります。組織の証跡 を設定することも、保護したいメンバーアカウントとリージョンで証跡を作成することもできます。
導入手順に進む前に、必ず以下の方法で作業環境を準備してください。

  1. GitHub Desktop のような Git クライアントのインストール
  2. AWS Command Line Interface (AWS CLI) のインストール
  3. Python3 と boto3 ライブラリのインストール

導入手順

  1. AWS CloudFormation テンプレートをログアーカイブアカウントにデプロイ
  2. AWS CloudFormation テンプレートをメンバーアカウントにデプロイ
  3. メンバーアカウントのサービスコントロールポリシー (SCP) を設定
  4. メンバーアカウントで Session Manager 用の EC2 インスタンスを設定
  5. 既存の IAM ポリシーを EC2 インスタンスプロファイルにアタッチ

ステップ1:AWS CloudFormation テンプレートをログアーカイブアカウントにデプロイ

このソリューションには、CloudFormation テンプレートを選択したリージョンにデプロイするための既製のスクリプトが付属しています。以下の手順を実行する前に、必ずログアーカイブアカウントの指定された IAM プリンシパルのセキュリティ認証情報を使用して、デフォルトの AWS CLI プロファイル を設定してください。

# Clone the repository
git clone https://github.com/aws-samples/ssm-monitoring-logging-guardrails-multiaccount.git

# Switch directories
cd aws-ssm-monitoring-logging-guardrails-multiaccount

# Run deployment script (insert AWS Region without quotes)
make deploy-log-archive-stack AWSRegion=<AWSRegion>

CloudFormationスタックが作成されたら、生成された出力を必ず書き留めてください。

  • CentralSSMSessionLoggingS3BucketName – セッションログ集約用の S3 バケットの名前
  • CentralSSMSessionMonitoringSecurityComplianceSNSTopicArn – アラート通知用の SNS トピックの ARN
  • CentralSSMSessionMonitoringKMSKeyArn – Systems Manager Session チャンネル、SNS トピック、S3 オブジェクトを暗号化するための AWS KMS キーの ARN。

次のスクリプトを使用して、後から出力を取得することもできます。

# Get stack outputs from your log archive account
make describe-log-archive-stack-outputs AWSRegion=<AWSRegion>

次のステップに進む前に、作成したアラート SNS トピックへの Eメールサブスクリプション を設定して、ソリューションが発行するセキュリティ通知をテストできるようにすることを検討してください。

ステップ2:AWS CloudFormation テンプレートをメンバーアカウントに デプロイ

ステップ 1 で取得した値を、メンバーアカウントにリソースをデプロイするスクリプトに渡します。以下の手順を実行する前に、そのメンバーアカウントから指定された IAM プリンシパルのセキュリティ認証情報を使用してデフォルトの AWS CLI プロファイル を設定してください。

# Run deployment script (insert all values without quotes)
make deploy-member-account-stack AWSRegion=<AWSRegion> \
CentralSSMSessionLoggingS3BucketName=<CentralSSMSessionLoggingS3BucketName> \
CentralSSMSessionMonitoringKMSKeyArn=<CentralSSMSessionMonitoringKMSKeyArn> \
CentralSSMSessionMonitoringSecurityComplianceSNSTopicArn=<CentralSSMSessionMonitoringSecurityComplianceSNSTopicArn>

スクリプトが完了したら、オプションでメンバーアカウントにログインし、次のようなテンプレートの追加入力パラメータを使用して aws-ssm-guardrails-org-member-account スタックを更新できます。

  • SessionManagerIdleSessionTimeout – 非アクティブな SSM セッションのタイムアウトしきい値(分単位で設定)
  • StepFunctionStateSleepSeconds – AWS Step Functions ステートマシンがセッションコンプライアンスを検証する頻度
  • TerminatedSessionsAlertThreshold – アラートがSNS トピックに送信されるまでに許容される終了セッション数の 5 分間のしきい値

ステップ3:メンバーアカウントのサービスコントロールポリシー (SCP) を設定する

AWS Organizations 管理アカウントまたは 委任管理者アカウント にログインします。次に、AWS Organizations コンソールに移動し、ステップ 2 のメンバーアカウントに 次のSCPをアタッチします。

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
        { 
            "Sid": "DenyModifyDocument", 
            "Effect": "Deny", 
            "Action": [ 
                "ssm:UpdateDocument", 
                "ssm:CreateDocument", 
                "ssm:DeleteDocument" 
            ], 
            "Resource": [ 
                "arn:aws:ssm:*:*:document/SSM-SessionManagerRunShell" 
            ] 
        }, 
        { 
            "Sid": "ProtectPolicy", 
            "Effect": "Deny", 
            "Action": [ 
                "iam:Create*", 
                "iam:Delete*" 
            ], 
            "Resource": [ 
                "arn:aws:iam::*:policy/aws-ssm-guardrails-mandatory-policy-*" 
            ] 
        }, 
        { 
            "Sid": "ProtectAlarm", 
            "Effect": "Deny", 
            "Action": [ 
                "cloudwatch:PutMetricAlarm", 
                "cloudwatch:Disable*", 
                "cloudwatch:Delete*" 
            ], 
            "Resource": [ 
                "arn:aws:cloudwatch:*:*:alarm:aws-ssm-monitoring-logging-guardrails-multiaccount" 
            ] 
        }, 
        { 
            "Sid": "ProtectSNSTopicByArn", 
            "Effect": "Deny", 
            "Action": [ 
                "sns:AddPermission", 
                "sns:RemovePermission", 
                "sns:Create*", 
                "sns:Delete*" 
            ], 
            "Resource": [ 
                "arn:aws:sns:*:*:aws-ssm-monitoring-logging-guardrails-multiaccount" 
            ] 
        }, 
        { 
            "Sid": "ProtectStateMachineByArn", 
            "Effect": "Deny", 
            "Action": [ 
                "states:DeleteStateMachine", 
                "states:CreateStateMachine", 
                "states:UpdateStateMachine", 
                "states:StopExecution" 
            ], 
            "Resource": [ 
                "arn:aws:states:*:*:stateMachine:aws-ssm-monitoring-logging-guardrails-multiaccount-statemachine", 
                "arn:aws:states:*:*:execution:aws-ssm-monitoring-logging-guardrails-multiaccount-statemachine:*" 
            ] 
        }, 
        { 
            "Sid": "ProtectOtherSolutionResourcesByArn", 
            "Effect": "Deny", 
            "Action": [ 
                "iam:*", 
                "lambda:Delete*", 
                "lambda:Put*", 
                "lambda:Remove*", 
                "lambda:Publish*", 
                "lambda:Update*", 
                "lambda:AddPermission", 
                "lambda:RemovePermission", 
                "events:*", 
                "cloudformation:*" 
            ], 
            "Resource": [ 
                "arn:aws:iam::*:role/solution/*", 
                "arn:aws:lambda:*:*:function:check-ssm-session-target-iam-role-compliance-function", 
                "arn:aws:lambda:*:*:function:check-ssm-session-status-function", 
                "arn:aws:lambda:*:*:function:check-ssm-session-s3-log-existence-function", 
                "arn:aws:events:*:*:rule/aws-ssm-monitoring-logging-guardrails-multiaccount*", 
                "arn:aws:cloudformation:*:*:stack/aws-ssm-guardrails-org-member-account/*" 
            ] 
        } 
    ] 
}

上記は、現在 AWS Organizations リソースをコードで管理 している場合に限り、AWS CloudFormation でも実現できます。

ステップ 4:メンバーアカウントで Session Manager の EC2 インスタンスを設定

以下の前提条件に基づいて、同じリージョンのメンバーアカウントで EC2 インスタンスを Systems Manager 管理ノード に登録します。AmazonSSMManagedInstanceCore などの Session Manager 権限を持つ IAM ポリシー がインスタンスプロファイルにアタッチされていることを確認してください。必要に応じて、セッションを開始するための適切な権限 を持つ IAM ユーザーまたはIAM ロールを作成します。

セキュリティ体制をさらに改善する手段として、Session Manager のVPCエンドポイントの設定も検討してください。S3、KMSも同様です。

ステップ 5: IAM ポリシーを EC2 インスタンスプロファイルにアタッチ

ステップ 2 が完了すると、CloudFormation スタックの一部として、保護対象のメンバーアカウントに次の IAM ポリシーが作成されているはずです。

arn:aws:iam::${AWS::AccountId}:policy/aws-ssm-guardrails-mandatory-policy-${AWS::Region}

ポリシーには次の内容が含まれます。

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
        { 
            "Action": [ 
                "kms:Decrypt", 
                "kms:GenerateDataKey" 
            ], 
            "Resource": [ 
                "arn:aws:kms:${AWS::Region}:{LogArchiveAccountId}:key/{KeyId}" 
            ], 
            "Effect": "Allow" 
        }, 
        { 
            "Action": [ 
                "s3:PutObject", 
                "s3:PutObjectAcl", 
                "s3:GetEncryptionConfiguration" 
            ], 
            "Resource": [ 
                "arn:aws:s3:::central-log-ssm-audit-${AWS::Region}-{OrganizationId}/{MemberAccountId}/*", 
                "arn:aws:s3:::central-log-ssm-audit-${AWS::Region}-{OrganizationId}" 
            ], 
            "Effect": "Allow" 
        } 
    ] 
}

この IAM ポリシーは EC2 インスタンスプロファイルにアタッチする必要があります。これが完了したら、Session Manager からセッションを開始 し、ログアーカイブアカウントの S3 バケットで生成されたログの内容を調べることで、ソリューションをテストできます。

central-log-ssm-audit-${AWS::Region}-${OrganizationId}

さらに、上記のポリシーをインスタンスプロファイルから削除することで、悪意のあるアクティビティをシミュレーションできます。以下の画像に示すように、IAM コンソールで適切なロール定義に移動し、「Permissions」タブからポリシーをデタッチします。

図 3. 攻撃者のアクティビティのシミュレーション

このアクションにより、セッションが終了し、セキュリティ通知が受信トレイに送信されるはずです (事前に中央の SNS アラートトピックへのサブスクリプションを設定している場合)。

クリーンアップ

ステップ 1: サービスコントロールポリシー (SCP) をデタッチして削除する

リソースをクリーンアップするには、まず、デプロイ手順のステップ 3 で作成したサービスコントロールポリシー (SCP) をそれぞれのメンバーアカウントからデタッチして削除する必要があります。そのためには、AWS Organizations の管理アカウントまたは委任された管理者アカウントにログインします。

ステップ 2:メンバーアカウントからリソースを削除する

次のステップでは、以下のスクリプトを使用してメンバーアカウントからリソースをクリーンアップします。

# Delete aws-ssm-guardrails-org-member-account stack
make delete-member-account-stack AWSRegion=<AWSRegion>

ステップ 3:ログアーカイブアカウントからリソースを削除する

すべてのメンバーアカウントからソリューションを削除したら、ログアーカイブアカウントに対して次のコマンドを実行します (そのアカウントの適切な IAM プリンシパルを反映するように AWS CLI 認証情報を更新することを忘れないでください)。

# Delete aws-ssm-guardrails-log-archive-account stack
make delete-log-archive-stack AWSRegion=<AWSRegion>

デフォルトでは、クリーンアップスクリプトは完了時にリソースを保持しません。両方の S3 バケット (セッションログ、アクセスログ) を空にして削除し、KMS キーの削除をスケジュールします。ただし、デプロイ手順のステップ 2 でテンプレートパラメーター「isProductionDeployment」を「true」に設定すると、S3 バケット内のデータは保存され、S3 リソースと KMS リソースの両方が DeletionPolicy によって保護されます。

その他の考慮事項

SSH への直接アクセスをブロック

このソリューションでは、追加のガードレールを使用して EC2 インスタンスへの直接の SSH アクセスをブロックすることに注意してください。このブログ記事では触れませんが、AWS Firewall Manager コンテンツ監査セキュリティグループポリシー は、これを実現するための実行可能なオプションの 1 つです。

ネットワークの構成ミス

セキュリティグループやネットワーク ACL の設定ミスが原因で、SSM エージェントが中央のS3 および KMS リソースにアクセスできなくなる可能性があります。このような場合、ソリューションはセッションが完了するとセキュリティインシデント通知を送信し、セキュリティチームによるさらなる調査を促します。必要に応じて、顧客は (VPC Reachability Analyzer を使用するなどして) このようなリスクに迅速に対応するために、より高度な検出または予防策をソリューションに追加できます。

ソリューションのコスト

StepFunctionStateSleepSeconds テンプレートのパラメータ値を調整することで、AWS リソースのコストとセキュリティリスクのバランスを取ることができます。このパラメータは、ソリューションが継続的なセッションコンプライアンスをチェックする頻度を決定します。StepFunctionStateSleepSeconds をデフォルトの 15 秒に設定して 10 分間のセッションをモニタリングする場合のコストは、約 0.008 USD (us-east-1 リージョンに基づく価格) です。パラメータ値を調整すると、セッションごとのコストを増減できます。

CloudTrail インテグレーション

このソリューションでは、AWS CloudTrail と Amazon EventBridge を利用して、ユーザーが新しいセッションを開始したことを通知します。CloudTrail からのイベントは、EventBridge が ベストエフォートで配信することに注意してください。つまり、CloudTrail はすべてのイベントを EventBridge に送信しようとしますが、ごくまれにイベントが配信されないことがあります。

ログの保持

費用対効果を高めるため、このブログ記事に含まれるコードでは、中央の S3 ロギングバケットのライフサイクルポリシーを設定し、ログオブジェクトの保存期間を限定できるようにしています。ただし、特定のセキュリティ要件を満たす場合は、ライフサイクルポリシーを無効にして、MFA Delete による追加の保護を検討してください。

ログストリーム

デフォルトでは、ソリューションはセッションデータのロギングにS3をターゲットにします。ただし、(CloudFormationパラメータを介して)CloudWatch Logs への配信を利用するように再設定することもできます。その後、ほぼリアルタイムの SIEM 統合を目的として一元化できます。このオプションを利用する場合に備えて、CloudWatch のログ取り込みとストレージに追加のコストがかかることを覚えておいてください。

Cloud9 サポート

Session Manager を利用して、AWS Cloud 9 環境へのセッションを確立できます。ただし、この接続にはポートフォワーディングが必要なため、上記のソリューションでは終了してしまうことに注意してください。

結論

Session Manager では、IAM ロールを使用しながら、インバウンドポートを開かずに EC2 インスタンスにアクセスできます。このブログ記事では、脅威の検出、インシデント対応、フォレンジック、ログのアーカイブを目的として、すべてのセッションアクティビティが中央アカウントに記録されるように、Session Manager に追加のガードレールを適用する方法を説明しました。特定のユースケースへの導入に役立つ追加のパラメータオプションを含め、GitHub のソリューションコードを自由に確認してください。

Mladen Trampic

Mladen は AWS エンタープライズサポートEMEA のシニアテクニカルアカウントマネージャーです。Mladen は、AWS のお客様が信頼性とコスト効率を重視して設計を行い、オペレーション エクセレンスの向上を支援します。仕事をしていないときは、娘と一緒にホームラボでコンピューターを作ったり、新しいことを学んだりすることを楽しんでいます。

Alan Pilawa

Alan は、主に金融サービス部門で働くシニア テクニカルアカウントマネージャーです。AWS のセキュリティ、信頼性、運用上の懸念があるお客様を支援しています。仕事をしていないときは、自宅の小さなスタジオで電子音楽を作成することを楽しんでいます。

翻訳はテクニカルアカウントマネージャーの日平が担当しました。原文は こちら です。