Session Manager で Amazon Linux 2 にリモート接続して、コマンドログを取得する

# はじめに

AWS で EC2 インスタンスや RDS 等を構築したときに、どのようにアクセスをしていますか。よくあるのが、Public Subnet に踏み台サーバーを構築し、Security Group で特定の IP アドレスに限定してアクセスする方法です。特定の IP アドレスに限定させているので、大きな問題はないですが、それでもシステムに入るための入り口としての踏み台サーバーが、Public IP を持っているのはセキュリティ的に気になります。Public IP の削除が出来るのであれば、よりセキュアに構成ができます。

構成図で表すと、こんな感じです。

![image-20221226224535387.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c6054bd1-80f8-8ac4-7efe-71c70d0e8e9f.png)



こういった課題感を解決するために、Session Manager で上記構成図の踏み台サーバーを無くすことが出来ます。Private Subnet に配置した EC2 インスタンスに直接リモートアクセスが出来るので、踏み台サーバー経由の侵入を防ぐことが出来ます。

![image-20221226225150037.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/90d77441-3545-a099-3682-4893f0e73c27.png)



この記事では、Session Manager の使い方を簡単に確認してみる内容となっています。



# IAM Role の作成

以下の Document に従って、IAM Policy と、それに紐づく IAM Role を作成します。詳細は省略します。

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



Policy の JSON

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel",
                "ssm:UpdateInstanceInformation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetEncryptionConfiguration"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "kms:GenerateDataKey",
            "Resource": "*"
        }
    ]
}
```



# EC2 Instance の作成

Session Manager を使ったリモートアクセスとして、適当に EC2 インスタンスを作成します。

OS は Amazon Linux 2 を選択します。Amazon Linux 2 には、ssm-agent が既にインストールされているため、楽に検証できます。

![image-20221226233257610.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c14e0e79-aa89-c78e-379d-f80ca38b0bb6.png)



Instance Profile に、先ほど作成した IAM Role を指定します。

![image-20221226233355810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/6dfc2837-7aa1-e6e1-ca8e-d9ac00208e9a.png)



ネットワークなどは適当に指定して、Launch Instance で作成します。

![image-20221226233451455.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d4eb34ea-9d7d-b62d-95ca-e11c2156e302.png)



Instance が作成されました。

![image-20221226235911366.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f6101d23-0c10-d9d8-4828-d81ee9bfae8e.png)



作成すると、自動的に Systems Manager の Fleet Manager に EC2 インスタンスが登録されています。これを使って、Session Manager を使ったリモートアクセスが可能です。

![image-20221227000026046.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/513dc141-2bb1-8926-a2f4-8a2b6b3aa0fa.png)



# Session Manager の接続方法

Session Manager を使った接続の方法には、いくつかの方法があります。個人的には以下の 4 つが代表的なものだと思います。それぞれ接続方法を確認してみましょう。

- マネージメントコンソールを使った接続 (Systems Manager Console)
- マネージメントコンソールを使った接続 (EC2 Console)
- AWS CLI で、リモート接続
- AWS CLI で、ポート転送で接続



上記 4 つ以外の方法は、[AWS Document に一覧化](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html)されているので、興味があれば Document もどうぞ。



# マネージメントコンソールを使った接続 (Systems Manager Console)

Session Manager の画面で、Start Session を押します。

![image-20221227215025348.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ef036a33-bcd5-cb72-c707-783d4f863355.png)



Start Session

![image-20221227215132939.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b05cf1ec-4448-0df7-d497-885e4120150c.png)



ブラウザ上で、Amazon Linux 2 の環境に、リモート接続できました。

![image-20221227215157574.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b461f3d9-3b2c-ddd7-ecd3-8027a66ba5cc.png)



ユーザー `ssm-user` でリモート接続がされます。sudo コマンドが実行できるので、root ユーザーや ec2-user にスイッチが出来ます。

![image-20221227215221181.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a58d2176-539f-6be2-68ec-4e84a61e8db7.png)



Session Manager のセッション上でキー入力した情報は、CloudWatch Logs に自動的に送付されます。監査ログとして保管をしても良いでしょう。

![image-20221227215802811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/15d8fe0b-ba0b-0605-cbb1-1ce09ebea0d4.png)



Log stream を開きます。

![image-20221227215820034.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/92a80c49-2598-d1bc-c1e2-f3fd0edf3983.png)



ログが取得されています。次の情報がわかります。

- Amazon Linux 2 上で実行したコマンドのログ
- 実行時間
- Session Manager で接続した User 名

![image-20221227215920656.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/7799f48a-8985-ee3b-4b59-712f40fe3913.png)



# マネージメントコンソールを使った接続 (EC2 Console)

EC2 Instance の Console 画面経由でも、Session Manager を開けます。対象のインスタンスを選択して、Connect を押します。

![image-20221227222318477.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/eb635074-66e7-22b8-5d69-a9ca9f4e6ce7.png)



Session Manager を選択して、Connect を押します。

![image-20221227222336009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/14bdae7f-bd73-877d-645c-88218c310f44.png)



さきほどと同様に、Session Manager を使った接続が出来ました。接続した後の画面は、さっきと同じです。

![image-20221227222427883.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c5f6bf85-92a9-7912-72a7-3aae8b929c50.png)



実行したコマンドが、CloudWatch Logs に取得されています。

![image-20221227223100289.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/989e385e-f125-ad0c-cd53-624b752aaa0b.png)



# AWS CLI で、リモート接続

AWS CLI をインストールしている環境からも、リモート接続が可能です。

次のコマンドを実行します。

```
aws ssm start-session --target i-04c2e28d623aab574
```



実行例

```
> aws ssm start-session --target i-04c2e28d623aab574 --profile sub2

Starting session with SessionId: cliuser-0caa0dc5ee42e1294
sh-4.2$
```



ブラウザで接続したように、リモート接続ができています。このセッション上で、さまざまなコマンドの実行ができます。

![image-20221227222816773.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/53c65e9b-9630-6874-3273-d7df1f0a026a.png)



CloudWatch Logs にログが取得されています。

![image-20221227230332110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/88a9ca37-7efe-7bc4-611f-714d6fb61b99.png)





# AWS CLI で、ポート転送で接続

いままでとちょっと毛色が違うのですが、Session Manager を使ってポート転送ができます。今までの接続方法と違って、任意のポートに転送できるので、SSH 以外にも RDP や MySQL など、いろいろな接続ができます。

次のコマンドでポート転送を指定します。

- portNumber : 接続先のポート番号を指定します。今回は 22 を指定しているので、SSH をするためのポートです。
- localPortNumber : ローカルのポート番号を指定します。2222 を指定しています。

```
aws ssm start-session \
    --target i-04c2e28d623aab574 \
    --document-name AWS-StartPortForwardingSession \
    --parameters '{"portNumber":["22"], "localPortNumber":["2222"]}'
```



実行例

![image-20221227225129697.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/32644e89-8102-b478-9ca7-4492abd31544.png)



上記のコマンドを実行した結果、localhost の 2222 ポートが、EC2 側の 22 ポートにフォワーディングされます。次のようにポート番号を指定して、SSH 接続をしてみます。

```
ssh ec2-user@localhost -p 2222
```



SSH で接続できました

- あくまて SSH のポート転送なので、ログインしているユーザーは ec2-user

![image-20221227225202095.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d6fa3d16-a9d7-1318-389b-d0bf2574bfd1.png)



CloudWatch にログは収集されません。



# 検証してわかったこと

- Session Manager で取得できる Linux 上のコマンドのログは、少し見にくいところもある
  - Linux Shell 上で入力されたキーボード押下が記録されるので、backspace で文字を削除したところも文字として記録されるように見えている。そのためちょっと見にくい
![image-20221227223840580.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f42a6952-e7ce-dbeb-639a-a262b35e0c6c.png)

- Session Manager で OS 内のコマンド実行ログを収集してくれるのは、ポート転送ではないシンプルな `start-session` を使った接続のみ
  - RDS も同様にログが取得できない。Session Manager 以外のログ収集の仕組みを検討することは可能。



# 参考 URL

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html