【AWS】Systems Manager でセッション暗号化 & セッションログ保存しようとしたらどハマりした話


# はじめに

Systems Manager は色々なことができますが、中でも Session Manager は踏み台なくして EC2 に接続できる便利機能です。踏み台が廃止できるうえ、セッション暗号化がサポートされて更なるセキュリティ向上ができる！と思い、セッション暗号化とセッションログ保存をしようとしたところ結構ハマったので、やり方とハマりポイントを共有します。

![SystemsManager.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/3dbe27e2-2e89-7b91-49e6-a8e3ec20d139.jpeg)

ちなみに、Session Manager 絡みの話は巷に溢れていますが、断片的なものが多いと感じたので本記事では以下を網羅的にまとめることを意識しています。

- Session Manager で EC2 に接続するための基本設定
- セッション暗号化に必要な設定
- セッションログ保存に必要な設定

:::note warn
記事を Qiita CLI に移行したことに伴い、体裁を修正しました。ただし、内容の更新まではしていませんので、ご留意ください。
:::

## Session Manager で暗号化が必要な理由

Session Manager はマネジメントコンソールや AWS CLI から EC2 に接続できる機能です。
セッションを暗号化することで以下メリットがあります。

- セキュリティ強化できるので機密情報のやり取りも安心
- Fleet Manager でパフォーマンスカウンターやプロセスが表示できる ※超便利！

https://aws.amazon.com/jp/about-aws/whats-new/2019/04/AWS-Systems-Manager-Session-Manager-Enables-Session-Encryption-Using-Customer-Keys/

https://dev.classmethod.jp/articles/fleet-manager-kms/

セキュリティ考えたらセッションログの保存も必須、と考えたのが沼への入り口でした。。。

# まずは結論から

以下設定を行います (沢山あります)。

## (1) Session Manager で EC2 に接続するための基本設定

- SSM Agent のインストール -> Systems Manager の **高速セットアップ** が便利
- Session Manager を使うための IAM ポリシー付与(EC2)
  - **AmazonSSMManagedInstanceCore** を付与すれば OK
- Session Manager を使うための IAM ポリシー付与(ユーザー): **AdministratorAccess** が付与されているなら OK、個別設定する場合は以下を付与
  - **ssm:StartSession**
  - **ssm:TerminateSession**
  - **ssm:ResumeSession**
- VPC エンドポイントの作成(プライベートサブネットに配置した EC2 の場合)
  - **ec2messages._region_.amazonaws.com**
  - **ssm._region_.amazonaws.com**
  - **ssmmessages._region_.amazonaws.com**

## (2) セッション暗号化に必要な設定

- KMS キーの作成
- 暗号化のための IAM ポリシー付与(EC2)
  - **kms:Decrypt**
- 暗号化のための IAM ポリシー付与(ユーザー)
  - **kms:GenerateDataKey**
- VPC エンドポイントの追加(プライベートサブネットに配置した EC2 の場合)
  - **kms._region_.amazonaws.com**

## (3) セッションログ保存に必要な設定

- 保存先 CloudWatch ロググループ、S3 バケットの作成
- CloudWatch へログ保存するための IAM ポリシー付与(EC2): **CloudWatchAgentServerPolicy** が付与されているなら追加不要、個別設定する場合は以下を付与
  - **logs:CreateLogStream**
  - **logs:PutLogEvents**
  - **logs:DescribeLogGroups**
  - **logs:DescribeLogStreams**
- S3 へログ保存するための IAM ポリシー付与(EC2)
  - **s3:PutObject**
  - **s3:GetEncryptionConfiguration** (S3 バケットの暗号化が有効になっている場合)
- VPC エンドポイントの追加(プライベートサブネットに配置した EC2 の場合)
  - **s3._region_.amazonaws.com**
  - **logs._region_.amazonaws.com**

# 解説

順を追って解説します。

## 0. 前提環境

- VPC

  - 最低 1 つの VPC
  - サブネット: プライベートサブネット x1, パブリックサブネット x2 (実際はプライベートサブネット 1 つだけあれば良いです)
    ![0.1_VPC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/a9b69000-fac2-d6af-a869-48c0700bd31d.png)
    ![0.2_Subnets.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/ff546e63-5bfd-a53b-9bdf-ce188205a6cf.png)

- EC2
  - セキュリティグループ: すべてのアウトバウンドを許可
  - EC2: Amazon Linux 2 (何でも良い)
    ![0.3_SG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/08c41504-ea10-f743-445c-fcfaacd54b99.png)
    ![0.4_EC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/6c6930ff-39df-4f62-54e0-0cf80713c344.png)

## 1. 基本設定

まずは暗号化しない通常の Session Manager の設定をします。

### 1.1 Session Manager の設定

高速セットアップの「Host Management」が便利です。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/quick-setup-host-management.html

1 から設定したい場合は、以下ドキュメントに従って設定します。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-getting-started.html

### 1.2 VPC エンドポイントの作成

プライベートサブネットの EC2 にアクセスできるよう VPC エンドポイントを作成します。

VPC エンドポイントは、必要な 3 つのサービス以外にパッチ適用などのために S3 へのエンドポイントも作成しておきます (この後の手順でも必要になります)。エンドポイントは AZ ごとに作る点に注意してください。

セキュリティグループでは、VPC 内からの **HTTPS(443) インバウンド** を許可します。

![1.1_VEP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/5d51a178-f264-e4c7-87d9-659fd33e0452.png)

:::note warn
人によってはまずここでハマると思います。
以下を参考にさせていただきましょう。

https://dev.classmethod.jp/articles/tsnote-private-ec2-ssm-vpc-endpoint/
:::

### 1.3 接続確認

問題なく設定できていれば、セッションマネージャーでの接続ができるようになります。

![1.2_SessionManager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/9fd0340e-3d56-c733-ad1c-059ca0b6ac0a.png)

![1.3_Session.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/1bf328ba-1804-6bc6-abfd-14ed876f2f52.png)

この時点では、Fleet Manager のパフォーマンスカウンターは見ることができません。

![1.4_FleetManager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/a80daf64-081b-06a1-f5b4-9cb280bd8de4.png)

## 2. セッション暗号化を有効にする

暗号化を有効にします。

### 2.1 KMS キーの作成

暗号化に必要な KMS キーを作成します。S3 や EBS などのように AWS マネージドキーがないため、カスタマーマネージドキーを作成します。

![2.1_KMS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/d508916e-f929-e0da-240e-b22e4fff5765.png)

### 2.2 暗号化のための IAM ポリシー付与

作成した KMS キーを使うための IAM ポリシーを作成して、EC2、IAM ユーザーに付与 (追加) します。

```json:EC2用の追加ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "kms:Decrypt",
            "Resource": "KMSキーのARN"
        }
    ]
}
```

```json:IAMユーザー用の追加ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "kms:GenerateDataKey",
            "Resource": "KMSキーのARN"
        }
    ]
}
```

### 2.3 KMS 用 VPC エンドポイントの追加

プライベートサブネットの EC2 が KMS にアクセスできるように KMS へのエンドポイントを作成します。セキュリティグループは上で作成したものと同じものを設定します。

ここまででエンドポイントは 5 つになっているはずです(S3 エンドポイントを作成していない場合は 4 つ)。

![2.2_VEP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/2716af35-0474-f944-e6d8-8da108bf0074.png)

:::note warn
ハマりポイント その 1 です。
EC2 から KMS に接続する必要があり、プライベートサブネットならさらにエンドポイントが必要という発想がありませんでした。
:::

### 2.4 Session Manager 暗号化設定

Systems Manager のセッションマネージャー設定で、暗号化を有効にします。KMS キーには先ほど作成したキーを指定します。

![2.3_SSMEncryption.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/1094d8be-cd68-7216-17d9-271c992e2d0c.png)

### 2.5 接続確認

設定に問題がなければ、セッションマネージャーで接続した際に「his session is encrypted using AWS KMS.」と表示されます (設定に不備があるとエラーが表示されます)。

![2.4_Session.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/8eada984-97ec-0f83-bcc9-604f8ff415b8.png)

また、Fleet Manager のパフォーマンスカウンターやプロセスが確認できるようになりました。

![2.5_Fleetmanager1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/b963c9fa-f667-ca24-e640-0871960e7580.png)

![2.6_FleetManager2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/97e22a2a-62c2-0df0-741c-85f47d93f399.png)

## 3. セッションログを保存する

セッションログの保存設定をします。保存先には **CloudWatch**、**S3** が個別に指定できます。ここでは、両方設定していきます。

### 3.1 ログ保存先 CloudWatch ロググループ、S3 バケットの作成

CloudWatch ロググループを作成します。ここまで読まれた方はセキュリティをガチガチに固めたいはずなので、もちろんロググループも暗号化します。

![3.1_CloudWatch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/7e7efddd-5a34-5e1b-4419-463c1f25adea.png)

先ほど作成した KMS キーを使用する場合は、キーポリシーに CloudWatch への使用許可を追加しましょう。

```json:CloudWatchで使用するためのキーポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::************:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        // 追加分ここから
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.ap-northeast-1.amazonaws.com"
            },
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:ReEncrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "*"
        }
        // ここまで
    ]
}
```

もう 1 つの保存先である S3 バケットを作成します。

![3.2_S3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/c7d71f39-6c53-2657-10c3-c99f082d9922.png)

S3 バケットももちろん暗号化しますが、こちらは AWS マネージドキーが使えます (aws/s3)。

![3.3_S3-KMS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/50f382c3-40a9-9f5b-5318-7f7c12b608d9.png)

### 3.2 ログ保存のための IAM ポリシー付与

CloudWatch にログを保存するため、EC2 に必要なポリシーを付与 (追加) します。CloudWatch エージェントを導入する前提で **CloudWatchAgentServerPolicy** が付与されていれば良いです。

S3 にログを保存するため、EC2 に以下のポリシーを付与 (追加) します。

```json:S3保存のためのポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "S3バケットのARN/*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:GetEncryptionConfiguration",
            "Resource": "*"
        }
    ]
}
```

:::note warn
ハマりポイント その 2 です。
追加で IAM ポリシーいるんだろうな、というのは何となく分かるのですが、何が必要かズバリの情報に辿り着くのに時間が掛かりました。
:::

### 3.3 CloudWatch 用 VPC エンドポイントの追加

プライベートサブネットの EC2 が CloudWatch にアクセスできるようにエンドポイントを作成します。もし S3 へのエンドポイントを作成していない場合はここで作成します。

全部でエンドポイントは 6 つになっているはずです。

![3.4_VEP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/a43252c0-f38b-a40d-70ff-5ecf4f02b7c4.png)

### 3.4 Session Manager ログ保存設定

Systems Manager のセッションマネージャー設定で、ログ保存を有効にします。上で作成した CloudWatch ロググループ、S3 バケットを指定します。セキュリティを考慮して、暗号化された保存先のみ許可する設定もオンにしておきます。

![3.5_SSMLoggingCloudWatch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/2ef69003-6b35-16a4-78cb-42eebf52bed1.png)

![3.6_SSMLoggingS3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372606/b619a31a-3af3-d987-d846-51fd31768897.png)

### 3.5 接続確認

おめでとうございます！！

設定に問題がなければ、セッションマネージャーでの接続が引き続きできるようになっているはずです (設定に不備があるとエラーが表示されたり、黒い画面のままプロンプトが出てきません)。

# さいごに

正直、セッション暗号化とログ保存を設定するためだけに、こんなに労力が掛かるとは思っていませんでした... が、おかげで Systems Manager、VPC、IAM にはだいぶ詳しくなれた気がします。

# 参考

以下記事を参考にさせていただきました。ありがとうございました。

https://zenn.dev/mn87/articles/a7173ec836b799

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-instance-profile.html

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/getting-started-restrict-access-examples.html

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-create-vpc.html#sysman-setting-up-vpc-create