こんにちは。AWS CLIが好きな福島です。
はじめに
今回は、マルチアカウント環境下におけるSession ManagerおよびRDP接続のログ設定方法をご紹介します。
構成概要
- ログ管理アカウントのS3にログを集約する
- ログ管理アカウントにKMSを作成し、ログの暗号化に利用する
- Session Managerのログは、自アカウントのCloudWatch Logsに出力
- CloudWatch LogsからData Firehoseを利用し、ログ管理アカウントのS3に出力
- RDP接続のログは、ログ管理アカウントのS3に直接出力
- Session ManagerおよびRDP接続のログ設定は、CloudFormation StackSetsを利用する
やること
- ①S3の作成
- ②KMSの作成
- ③Session ManagerおよびRDP接続のログ設定
- ④動作確認
今回は、Data Firehoseを利用したCloudWatch LogsからS3への出力設定の紹介は行いません。 詳細な手順は以下を参考にしていただければ幸いです。
①S3の作成
- S3バケットを作成します
aws s3api create-bucket \ --bucket central-logs-$(aws sts get-caller-identity --query Account --output text) \ --create-bucket-configuration LocationConstraint=ap-northeast-1
- バケットポリシー用のファイルを作成します
cat <<EOF > bucket-policy.json { "Version": "2012-10-17", "Statement": [ { "Sid": "ConnectionRecording", "Effect": "Allow", "Principal": { "Service": "ssm-guiconnect.amazonaws.com" }, "Action": "s3:PutObject", "Resource": [ "arn:aws:s3:::central-logs-$(aws sts get-caller-identity --query Account --output text)", "arn:aws:s3:::central-logs-$(aws sts get-caller-identity --query Account --output text)/*" ], "Condition": { "StringEquals": { "aws:SourceOrgID": "$(aws organizations describe-organization --query 'Organization.Id' --output text)" } } } ] } EOF
- バケットポリシーを作成します
aws s3api put-bucket-policy \ --bucket central-logs-$(aws sts get-caller-identity --query Account --output text) \ --policy file://bucket-policy.json
参考:
Recording RDP connections - AWS Systems Manager
②KMSの作成
- キーポリシー用のファイルを作成します
cat <<EOF > kms-policy.json { "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "AllowSSMGuiConnectKMSAccess", "Effect": "Allow", "Principal": { "Service": "ssm-guiconnect.amazonaws.com" }, "Action": [ "kms:GenerateDataKey", "kms:CreateGrant" ], "Resource": "*", "Condition": { "StringEquals": { "aws:SourceOrgID": "$(aws organizations describe-organization --query 'Organization.Id' --output text)" } } }, { "Effect": "Allow", "Principal": { "Service": "logs.amazonaws.com" }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:Describe*" ], "Resource": "*", "Condition": { "StringEquals": { "aws:SourceOrgID": "$(aws organizations describe-organization --query 'Organization.Id' --output text)" } } }, { "Sid": "Allow", "Effect": "Allow", "Principal": "*", "Action": "kms:createGrant", "Resource": "*", "Condition": { "StringEquals": { "aws:PrincipalOrgID": "$(aws organizations describe-organization --query 'Organization.Id' --output text)" } } } ] } EOF
AllowSSMGuiConnectKMSAccessの参考:
AWSSystemsManagerJustInTimeAccessTokenPolicy - AWS 管理ポリシー
- カスタマーマネージドキーを作成します
aws kms create-key \ --policy file://kms-policy.json \ --tags TagKey=Name,TagValue=SSMLogsKey TagKey=SystemsManagerJustInTimeNodeAccessManaged,TagValue=true
③Session ManagerおよびRDP接続のログ設定
- CloudFormation StackSetsを活用し、以下のテンプレートをデプロイします。
AWSTemplateFormatVersion: "2010-09-09" Description: Creates resources for encrypted session logging via CloudWatch and S3. Parameters: idleSessionTimeout: Type: Number Default: 20 Description: The idle session timeout in minutes. maxSessionDuration: Type: Number Default: 60 Description: The maximum session duration in minutes. RetentionInDays: Type: Number Default: 3 Description: The number of days to retain CloudWatch logs. KMSKeyArn: Type: String Description: The ARN of the KMS key to encrypt session logs. S3BucketName: Type: String Description: The name of the S3 bucket to store session logs. S3BucketOwner: Type: String Description: The AWS account ID of the S3 bucket owner. Resources: SessionManagerLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub session-manager-log-${AWS::AccountId} RetentionInDays: !Ref RetentionInDays KmsKeyId: !Ref KMSKeyArn SessionManagerLogAccessPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: session-manager-log-access-policy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:DescribeLogGroups - logs:DescribeLogStreams Resource: "*" - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub ${SessionManagerLogGroup.Arn} SessionPreferencesDocument: Type: AWS::SSM::Document Properties: UpdateMethod: NewVersion Name: SSM-SessionManagerRunShell DocumentType: Session DocumentFormat: JSON Content: { "schemaVersion": "1.0", "description": "Document to hold regional settings for Session Manager", "sessionType": "Standard_Stream", "inputs": { "cloudWatchLogGroupName": !Ref SessionManagerLogGroup, "cloudWatchStreamingEnabled": true, "cloudWatchEncryptionEnabled": false, "idleSessionTimeout": !Ref idleSessionTimeout, "maxSessionDuration": !Ref maxSessionDuration } } CuiConnectPreferences: Type: AWS::SSMGuiConnect::Preferences Properties: ConnectionRecordingPreferences: KMSKeyArn: !Ref KMSKeyArn RecordingDestinations: S3Buckets: - BucketName: !Ref S3BucketName BucketOwner: !Ref S3BucketOwner
CloudFormationでは、以下の設定を行なっています。
- EC2にアタッチするIAMポリシー作成
- ロググループの作成
- セッションマネージャーの設定
- リモートデスクトップ設定
④動作確認
ターミナルセッション接続のログを確認
- ターミナルセッション接続を実行する
- 任意のコマンドを実行する
- ロググループにログが出力されていることを確認できました!
リモートデスクトップ接続のログを確認
- リモートデスクトップ接続を実行する
- ID/PWを入力し、ログインする
- 任意の操作を行い、接続を終了する
- S3にログが出力されていることを確認できました!
ただ、こちらのログだけでは誰が操作したのか不明なため、 リモートデスクトップの接続履歴から接続IDを基に辿る必要がありそうです。
終わりに
今回は、マルチアカウント環境下におけるSession ManagerおよびRDP接続のログ設定方法をご紹介しました。
どなたかのお役に立てれば幸いです。