2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

とある会社のAdvent Calendar 2024

Day 22

AWS Systems Manager Session Managerのセッションロギング設定をAWS CDKで実装してみた。

Last updated at Posted at 2024-12-21

はじめに

AWS Systems Manager Session Manager(以降、Session Manager)とは、AWS Systems Managerの機能の一つで、Amazon EC2 for Linux(以降、EC2)に対してSSHを利用せずに接続できる機能となります。
Session Managerには、セッションロギング機能も提供されており、Session Manager経由で接続したセッションの操作ログを残すことが可能です。
Amazon CloudTrail(以降、CloudTrail)の操作ログはあくまでもSession ManagerからEC2へのセッションの開始/終了などのログしか記録されないので、EC2内での操作も証跡として残したい場合は、Session Managerのセッションロギング機能を有効化するのがよさそうです。

ロギングの有効化設定はマネージメントコンソールやAWS CDK(以降、CDK)などで可能なのですが、CDKの実装方法があまり出回っていないため、本記事でご紹介したいと思います。

前提条件

Session Managerを利用するためには、EC2が以下の条件を満たしている必要があります。

  • SSM Agentのインストール+起動
    • AWSが提供するAmazon Linuxはデフォルトで導入済み
  • IAMのAWSマネージドポリシーAmazonSSMManagedInstanceCoreのアタッチ
  • HTTPS (ポート 443) アウトバウンド・トラフィックの通信許可
    * EC2をプライベートサブネットに配置する場合は、NAT Gatewayもしくは以下のVPC Endpointを構築する必要あり
    * com.amazonaws.region.ssm
    * com.amazonaws.region.ssmmessages
    * com.amazonaws.region.ec2messages ※SSM Agentのバージョンが3.3.40.0以降の場合は不要

実装

CDKソースコードの構成図

今回は動作確認用に以下の構成図のAWSリソースを作成します。
session-manager-logging.drawio.png

CDKソースコード(スタックファイルのみ)

lib/session-manager-logging-stack.ts
import { Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import {
  Vpc,
  IpAddresses,
  SubnetType,
  SecurityGroup,
  Peer,
  Port,
  Instance,
  InstanceType,
  InstanceClass,
  InstanceSize,
  AmazonLinuxImage,
  AmazonLinuxGeneration,
} from "aws-cdk-lib/aws-ec2";
import { Bucket } from "aws-cdk-lib/aws-s3";
import { PolicyStatement } from "aws-cdk-lib/aws-iam";
import { CfnDocument } from "aws-cdk-lib/aws-ssm";

export class SessionManagerLoggingStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Session Managerログ保管用S3バケット
    const bucket = new Bucket(this, "MyBucket");

    // EC2向けVPC(パブリックサブネット1つのみ)
    const vpc = new Vpc(this, "MyVpc", {
      ipAddresses: IpAddresses.cidr("10.0.0.0/16"),
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: "public-subnet",
          subnetType: SubnetType.PUBLIC,
        },
      ],
      maxAzs: 1,
    });

    // EC2(アウトバウンド通信443のみ許可されたインスタンス)
    const securityGroup = new SecurityGroup(this, "MySecurityGroup", {
      vpc,
      allowAllOutbound: false,
    });
    securityGroup.addEgressRule(Peer.anyIpv4(), Port.tcp(443));
    const instance = new Instance(this, "MyInstance", {
      vpcSubnets: {
        subnetType: SubnetType.PUBLIC,
      },
      instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.NANO),
      machineImage: new AmazonLinuxImage({
        generation: AmazonLinuxGeneration.AMAZON_LINUX_2023,
      }),
      vpc: vpc,
      associatePublicIpAddress: true,
      securityGroup: securityGroup,
      ssmSessionPermissions: true, // EC2のRoleにAmazonSSMManagedInstanceCoreのPolicyがアタッチされる
    });
    // セッションログをS3に出力するための権限追加
    instance.addToRolePolicy(
      new PolicyStatement({
        actions: ["s3:GetEncryptionConfiguration", "s3:PutObject"],
        resources: [bucket.bucketArn, `${bucket.bucketArn}/*`],
      })
    );

    // Session Managerログ設定(SSMドキュメント)
    new CfnDocument(this, "MySessionManagerPreferences", {
      name: "SSM-SessionManagerRunShell",
      documentType: "Session",
      content: {
        schemaVersion: "1.0",
        description: "Document to hold regional settings for Session Manager",
        sessionType: "Standard_Stream",
        inputs: {
          s3BucketName: bucket.bucketName,
          s3EncryptionEnabled: true,
        },
      },
    });
  }
}

上記ソースコードを利用して環境をデプロイし、以降の動作確認を実施していきます。

動作確認

  1. マネージメントコンソールからEC2Session Managerで接続
    image.png
    接続後、ログ確認向けにいくつかコマンドを実行して、右上の「終了」ボタンを押下しセッションを終了します。
    image.png
  2. アップロードされたS3ログファイルを確認
    セッションを終了するとEC2からS3に対してセッションログが以下のスクショのとおりに出力されています。
    image.png
  3. セッションログファイル中身を確認
    セッションログをローカルにダウンロードして中身を見てみると以下のようにセッション内で実行したコマンドやその結果が記録されていました。
    ※ただしなぜか文字化けや不要な改行が含まれています。要因がわかっていません…。
    MatsuMikan-iskvzqvatbpxd3eynv64u9eqqa.log
    Script started on 2024-12-15 03:38:33+00:00 [<not executed on terminal>]
    [?2004hsh-5.2$ 
    [K
    sh-5.2$ s[Kpwd
    
    [?2004l
    /usr/bin
    
    [?2004hsh-5.2$ ua[Kname 0a[K[K-a
    
    [?2004l
    Linux ip-10-0-0-147.ap-northeast-1.compute.internal 6.1.115-126.197.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov  5 17:36:57 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
    
    [?2004hsh-5.2$ [7myum info amazon-ssm-agent[27m
    [C[C[C[C[C[C[C[Cyum info amazon-ssm-agent
    
    [?2004l
    Amazon Linux 2023 repository                           [===                                              ] ---  B/s |   0  B     --:-- ETA
    Amazon Linux 2023 repository                       56% [===========================-                     ]  55 MB/s |  17 MB     00:00 ETA
    Amazon Linux 2023 repository                       91% [============================================-    ]  54 MB/s |  27 MB     00:00 ETA
    Amazon Linux 2023 repository                                                                                35 MB/s |  29 MB     00:00    
    
    Amazon Linux 2023 Kernel Livepatch repository          [===                                              ] ---  B/s |   0  B     --:-- ETA
    Amazon Linux 2023 Kernel Livepatch repository                                                               54 kB/s |  11 kB     00:00    
    
    Installed Packages
    
    History database cannot be created, using in-memory database instead: SQLite error on "/var/lib/dnf/history.sqlite": Open failed: unable to open database file
    
    Name         : [36mamazon-ssm-agent(B[m
    
    Version      : 3.3.987.0
    
    Release      : 1.amzn2023
    
    Architecture : x86_64
    
    Size         : 125 M
    
    Source       : amazon-ssm-agent-3.3.987.0-1.amzn2023.src.rpm
    
    Repository   : @System
    
    Summary      : Manage EC2 Instances using SSM APIs
    
    URL          : http://docs.aws.amazon.com/ssm/latest/APIReference/Welcome.html
    
    License      : ASL 2.0
    
    Description  : This package provides Amazon SSM Agent for managing EC2 Instances using SSM APIs
    
    
    
    [?2004hsh-5.2$ 
    [K
    sh-5.2$ 
    [K
    sh-5.2$ 
    Script done on 2024-12-15 03:38:33+00:00 [COMMAND_EXIT_CODE="0"]
    

一部の文字化けは残念な感じではありますが、一応EC2内でどのようなコマンドが実行されているかの履歴を取得することができました。

上記ログ内容のとおり、セッションログはコマンド結果がもろにログに記録されます。
特にDBのコマンド(psqlなど)を実行するとそのコマンド結果もログに記録されますので、DBのSELECT結果がログに残ってしまう可能性があります。そういった仕様もご理解の上、セッションログの有効化有無をご検討いただくのがよいでしょう。
※公式のドキュメントには、コマンド実行時に秘匿情報を出力しないようなコマンド例はありますが、Session Managerの機能で特定のコマンド結果を出力しないように制御することはできない(2024/12時点)ので、ヒューマンエラーによりうっかりログ出力される危険性はあります。

トラブルシューティング

CDKのデプロイ時に'SSM-SessionManagerRunShell' already exists.のデプロイエラーが発生する

一度でもマネージメントコンソールからセッションロギング設定を有効化していると、
SSM-SessionManagerRunShellのドキュメントが既に存在しているエラーが発生してしまいます。

エラーメッセージ
❌  SessionManagerLoggingStack failed: Error: The stack named SessionManagerLoggingStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE: Resource handler returned message: "Resource of type 'AWS::SSM::Document' with identifier 'SSM-SessionManagerRunShell' already exists." (RequestToken: 6ab45d62-c824-bf44-1d0b-dd991baadd2b, HandlerErrorCode: AlreadyExists)

本設定をCDKで管理したい場合は、作成済みのSSM-SessionManagerRunShellドキュメントを削除すればよいのですが、マネージメントコンソール上では削除できないため、AWS CLIでの削除が必要になります。

削除コマンド
aws ssm delete-document --name SSM-SessionManagerRunShell

S3-KMSを利用しているS3に送付されない

S3のサーバーサイド暗号化にKMSを指定している場合には、EC2のIAMロールに以下二つのアクションを追加してください。

  • kms:Decrypt
  • kms:GenerateDataKey

補足

CloudTrailで取得できるSession Managerのログ

Session Managerでは主に以下のAPIを用いてEC2にセッションの操作を行いますので、CloudTrailでいつセッションを開始したか、または終了したかのログを追跡することは可能です。

  • StartSession: セッションを開始する
  • TerminateSession: セッションを終了する
  • ResumeSession: 接続されたセッションに再接続する

▼以下はStartSessionで絞り込んだスクリーンショット
image.png

マネージメントコンソールでの設定方法(2024/12時点、スクショのみ)

CDKのソースコードではSSM Documentを新規作成したのですが、マネージメントコンソール上では以下のようにセッションログ設定用の画面が用意されているので、こちらから設定することも可能です。

image.png

おまけ:CDK実装で困ったらAmazon Qに頼るもよし

実は、本設定のCDK実装はかなり苦戦しました。
マネージメントコンソール上での設定方法は把握していたものの、本設定がSSM Documentに関連していることに気づくことができず、CDKのリファレンスを探しても本設定方法になかなかたどり着きませんでした。
そんなときにおすすめなのが、Amazon Qで、今回はそちらを頼っていました(笑)。
image.png

本設定に限らず、CDKの実装で困ったことがあれば、Amazon Qに頼ってみるのも手ではないでしょうか。

おわりに

ニッチな記事ではございますが、CDKでセッションログの有効化を行いたい方や、セッションログの出力内容について、少しでも知見を共有できれば幸いです。

AWS re:Invent 2024の情報で盛り上がっている中、お付き合いくださりありがとうございました!

こちらからは以上です。

参考URL

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?