AWS SessionManagerを使ったEC2接続とアクセス制限のやり方

# 目次

1. はじめに
2. AWS SessionManagerを利用した接続の種類
   1. Webブラウザ版
   2. AWSCLI版
   3. AWSCLI版・ポート転送
3. AWS SessionManager接続のアクセス制限方法
4. AWS SessionManagerが利用するssm-userの特権の変更方法

# はじめに

AWSではEC2インスタンスへ接続する方法として、[AWS Session Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager.html) が提供されています。こちらの機能は AWS Systems Manager の一部として [2018年9月にリリース](https://aws.amazon.com/jp/blogs/aws/new-session-manager/) されました。その後、 [ポート転送の機能追加](https://aws.amazon.com/jp/blogs/news/new-port-forwarding-using-aws-system-manager-sessions-manager/) や [EC2コンソールへの統合](https://aws.amazon.com/jp/about-aws/whats-new/2019/12/session-manager-now-available-directly-from-amazon-ec2-console/) などを経て、現在はかなり活用しやすくなったと感じています。

AWS Session Managerでは、EC2インスタンスへの接続ポリシーをIAMで管理できるのが特徴です。従来のSSH接続と比べてセキュリティを強化し、運用コストを削減できます。

ただ実際に導入を進めると、AWSCLIの導入可否やファイル転送の有無など、利用者の要件に応じて幾つかの方法から選んでもらう必要があり、利用者向けの説明を念入りに行う必要がありました。

そこで今回は、現時点で利用できるSSMエージェントを利用したEC2インスタンスへの接続方法を整理してみます。

# AWS SessionManagerを利用した接続の種類

まず、AWS SessionManagerの利用者側の要件として、3つのポイントを確認しておきます。

- 追加のアプリケーション（awscli＋session-manager-plugin）をインストールしてもよいか
- WinSCP等のファイル転送ソフトを利用するか
- リモートデスクトップを利用するか

要件に応じて、以下の3種類から適切な接続方法を選択します。

<img width="919" alt="image1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611598/38a6c8c8-8715-b60b-e366-bc9120d56254.png">


いずれの場合も、EC2インスタンスにはSSMエージェントが必要です。Amazon Linux以外ではインストールが必要ですので [AWS Systems Manager ユーザーガイド - SSM エージェント の使用](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/ssm-agent.html) を参照してください。

それぞれの接続方法について説明します。

## Webブラウザ版

Webブラウザ上でAWSマネジメントコンソールに接続して、SessionManager画面から利用します。アプリケーションの追加導入ができない場合、利用できるのはマネジメントコンソール版のみとなります。テキストのコピー＆ペースト処理など、TeraTermのような専用のターミナルアプリに比べて出来ることが少ないので、対応不可能な業務もありそうです。また、現時点でファイルの転送機能は無く、基本的にインスタンス内のデータを表示することしかできません。

<img width="438" alt="image2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611598/85822bc7-f911-7f7b-d31c-48ed21b55a34.png">


<img width="551" alt="image3 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611598/36aaa027-6c33-2e12-d0a2-2c650945bc22.png">



## AWSCLI版

AWSCLIコマンド経由で、EC2インスタンスのシェルにログインする方法です。Webブラウザ版と同様にファイル転送機能はありません。普段から使い慣れたAWSCLIを利用できるので、使い勝手を重視する場合はこちらを利用するのが良いと思います。

```powershell
PS> aws ssm start-session --profile <AWSCLI に設定済みのプロファイル名> `
--target <EC2インスタンスID>
```

## AWSCLI版・ポート転送

AWSCLI版のポート転送機能では、クライアントとEC2インスタンス間にトンネル接続を作成できます。トンネル接続を利用すると、任意のアプリケーションを使ってEC2インスタンス上のアプリケーションと安全に接続できます。例えば、WinSCPのようなGUI経由のファイル送受信や、リモートデスクトップ接続などでも、セキュリティグループでSSHポートやRDPポートを開放する必要がありません。

```powershell
PS> aws ssm start-session --profile <AWSCLIに設定済みのプロファイル名> `
--target <EC2インスタンスID> `
--document-name AWS-StartPortForwardingSession `
--parameters '{\"portNumber\": [\"<EC2 インスタンス側のポート番号>\"],\"localPortNumber\": [\"<ローカル側のポート番号>\"]}'
```

# AWS SessionManager接続のアクセス制限方法

SSMエージェントは、Linuxの場合はrootアクセス権限、Windowsの場合はSYSTEMアクセス権限を使用して、EC2インスタンスへアクセスします。SSMエージェントで接続できるIAMユーザやIAMロールと、対象のEC2インスタンスの特権アクセスを持つこととは、イコールです。

そのため、特権行使できる範囲を適切な方法で限定する必要があります。

## IAMポリシーを使用してインスタンス単位で接続を限定する方法

[AWSのユーザーガイド](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/ssm-agent-restrict-root-level-commands.html) では、IAMポリシーを使用したアクセス制限方法が掲載されています。

例えば、以下のようにインスタンスIDを含んだIAMポリシーを使用して、特定のインスタンスだけに接続許可を与えることも可能です。ただし、TerminateSessionを限定するため、終了できるセッションは自分で作成したセッションのみです。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:StartSession"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-2:123456789012:instance/i-1234567890EXAMPLE",
                "arn:aws:ec2:us-east-2:123456789012:instance/i-abcdefghijEXAMPLE",
                "arn:aws:ec2:us-east-2:123456789012:instance/i-0e9d8c7b6aEXAMPLE"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:TerminateSession"
            ],
            "Resource": [
                "arn:aws:ssm:*:*:session/${aws:username}-*"
            ]
        }
    ]

}
```

その他にも、EC2タグに基づいて制限する方法などもありますので、詳細は [AWS Systems Manager ユーザーガイド - 追加の Session Manager 用のサンプル IAM ポリシー](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/getting-started-restrict-access-examples.html#restrict-access-example-instance-tags) を参照してください。

# AWS SessionManagerが利用するssm-userの特権の変更方法

IAMポリシーを使用した接続許可設定を紹介しましたが、実際にはEC2インスタンス内においても、利用者ごとに制約を設けたいシーンは多いと思います。

Linuxの場合に限られますが、そのような場合は、AWS SessionManagerが利用するssm-userアカウントの特権を修正することで対応が可能です。

SSMエージェントが利用するssm-userアカウントは、以下のファイルに特権設定を作成しています。

```shell:/etc/sudoers.d/ssm-agent-users
# User rules for ssm-user
ssm-user ALL=(ALL) NOPASSWD:ALL
```

例えば、以下のように変更することで、OSグループごとに特権を割り当てることができます。

```shell:/etc/sudoers.d/ssm-agent-users
# User rules for ssm-user
ssm-user ALL=(%admin,%devel) ALL
Defaults:ssm-user targetpw
```

修正後の設定内容は以下の通りです。

- ssm-userは、adminグループ or develグループ に所属するユーザとして、全てのコマンドを実行できる
- 実行時はグループに所属するユーザのパスワードを必要とする

実際に利用する際は、以下のように ssm-userから各ユーザに切り替えて、特権昇格が可能です。

```shell
sh-4.2$ sudo -iu tanaka                <-- adminグループに所属するtaroユーザー
[sudo] password for tanaka: ********   <-- taroユーザーのパスワード
taro@web01 [~]                         <-- adminグループの権限を取得
```


# まとめ

AWS Session Managerを利用した接続方法と、アクセス制限方法を紹介しました。

AWS Session Managerによるポリシーの一元化は、今後のセキュリティ強化と運用コスト削減のための、ひとつの解となりそうです。AWSの機能アップデートに合わせて、利用者側の環境も積極的に追従していきたいですね。

以上です。