SSM Session ManagerのSSHトンネリング機能をAssumeRoleで利用する方法

記事タイトルとURLをコピーする

技術一課の杉村です。2019年7月、AWS Systems Manager Session ManagerでSSH/SCPセッションを利用できる機能が発表されました。 Session Manager launches tunneling support for SSH and SCP

この機能を利用すれば「踏み台インスタンス対してSession ManagerでSSHセッションを確立し、Private Subnetにいる他のEC2インスタンスに対してポートフォワードでアクセスする」のような、より柔軟な使い方できるようになります。

もちろん、SSH対象のEC2インスタンスのセキュリティグループではSSH用のポートを許可する必要はありません。 EC2インスタンスから443ポートでSystems ManagerのAPIエンドポイントに対してHTTPS通信ができさえすればいいのです。

この機能を利用する方法については、多くの方が既にブログを書かれていますので、今回のブログではさらに一歩進んで「AssumeRoleを使ってSSM Session ManagerのSSHトンネリング機能を使ってみる」という検証をしてみます。

AssumeRoleでSSM Session Manager(SSH Tunneling)って??

多数のAWSアカウントを管理している企業では、IAM Userを中央の管理用AWSアカウントに集約し、各AWSアカウント(サブシステムや部署、グループ会社など)にはスイッチロール(AssumeRole)させて利用している、ということがよくあります。

今回のブログではその構成に合わせて、以下のような利用方法を考えてみます。

※以下便宜上、IAM Userを集約するAWSアカウントを「中央AWSアカウント」と呼び、スイッチ(AssumeRole)先のAWSアカウントを「システム用AWSアカウント」と呼びます

1. システム用AWSアカウント(EC2の存在するAWSアカウント)にIAM Roleを作成。対象EC2にStartSessionできる権限を付与 2. 中央AWSアカウントに利用者用IAM Userを作成。前述のIAM RoleをAssumeRoleできる権限を付与 3. 利用者は中央AWSアカウントに作成したIAM UserのCredentialを使ってSSHセッションを確立する

これにより、中央AWSアカウントにIAM Userを集約するという運用を崩すことなく、SSM Session ManagerのSSHトンネリング機能を利用することができます。 構成は下記の図のようになります。

なお、これから記載する手順では、EC2側の手順(SSM AgentのインストールやIAM Roleの付与)は完了している前提で記載します。※下記リンクのStep1 & Step2が該当 Getting Started with Session Manager

1. システム用AWSアカウント(EC2の存在するAWSアカウント)にIAM Roleを作成

IAM Roleを作成し、以下のポリシーをアタッチします。 ※<System-AWS-Account-ID>と<EC2-Instance-ID>の部分は任意の値に書換え。アスタリスクが利用可能

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:StartSession"
            ],
            "Resource": [
                "arn:aws:ec2:ap-northeast-1:<System-AWS-Account-ID>:instance/<EC2-Instance-ID>",
                "arn:aws:ssm:ap-northeast-1::document/AWS-StartSSHSession"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:TerminateSession"
            ],
            "Resource": [
                "arn:aws:ssm:*:*:session/${aws:username}-*"
            ]
        }
    ]
}

信頼関係ポリシーでは以下のように、IAM Userのいる中央AWSアカウントからAssumeRoleできるよう記述します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::<Central-AWS-Account-ID>:root",
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

RoleのARNは後ほど使うため、メモします。

2. 中央AWSアカウントに利用者用IAM Userを作成

中央AWSアカウントに利用者用のIAM Userを作成します。 同IAM Userには、下記のようなポリシーをアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::<System-AWS-Account-ID>:role/<Role-Name>"
        }
    ]
}

つまり、IAM Userに与える権限は、RoleをAssumeする権限だけです。

3. クライアントPC側の設定

クライアントPCがWindowsマシンである前提です。

3-1. AWS CLIとSession Manager Pluginのインストール

下記の手順でAWS CLIをインストールします。既にインストール済の場合でもバージョンが1.16.12以降である必要がありますので、必要があればアップデートします。 Windows に AWS CLI をインストールする

その後、下記の手順でSession Manager Plugin for the AWS CLIをインストールします。 (オプション) AWS CLI 用の Session Manager Plugin をインストールする

3-2. IAMクレデンシャル情報の設定ファイル

IAM UserのCredential (AccessKeyとSecret AccessKey)を、ファイル"C:\Users\<ユーザ名>\.aws\credentials"に記述します。

[default]
aws_access_key_id = AKIA****************
aws_secret_access_key = <Secret AccessKey>

そしてファイル"C:\Users\<ユーザ名>\.aws\config"に以下のように記載します。

[profile assumeRoleProfile]
region = ap-northeast-1
role_arn = arn:aws:iam::<System-AWS-Account-ID>:role/<Role-Name>
source_profile = default

※プロファイル名は任意です これらの設定ファイルの記述により、AWS CLIのコマンド実行時にプロファイル"assumeRoleProfile"を指定することで、AssumeRoleで得た一時認証情報でAPIコールを実行することができるようになります。

3-3. SSHクライアントのインストールと設定ファイル準備

コマンドプロンプトでsshコマンドが利用できるよう、OpenSSHコマンドをインストールします。 (方法は当ブログではご紹介しませんが、ググるとたくさんでてきます)

その後、ファイル"C:\Users\<ユーザ名>\.ssh\config"に以下を記述します。

# SSH over Session Manager
host i-* mi-*
    ProxyCommand C:\Program Files\Amazon\AWSCLI\bin\aws.exe --profile assumeRoleProfile ssm start-session --target %h --document-name AWS-StartSSHSession --parameters "portNumber=%p"

ポイントは、awsコマンドをフルパスで記述すること、また --profileにて先ほど~\.aws\configファイルに設定したプロファイル名を記述することです。

これで準備が整いました。

4. SSHセッションの確立

以下のコマンドを実行し、ログインします。

ssh -i <Path-to-Secret-Key> <OS-User-Name>@<EC2-Instance-ID>

例: ssh -i C:\Users\hogehoge\.ssh\secretKey.pem ec2-user@i-1234567890abcdefg

参考まで、SSHトンネリングを利用してポートフォワードをすることもできます。 クライアントPCから踏み台まではSSHトンネルを張り、踏み台から先のPrivate Subnetに存在するEC2インスタンスにSSHやRDPをすることが可能です。

ssh -i C:\Users\hogehoge\.ssh\secretKey.pem -L 13389:10.10.0.4:3389 -L 23389:10.10.0.15:3389 ec2-user@i-1234567890abcdefg

※上記コマンドでSSHすれば、localhost:13389で10.10.0.4に、localhost:23389で10.10.0.15にRDPできます。  -Lを複数並べることで、複数のリモートホストに対するポートフォワードが設定できます。

杉村 勇馬 (記事一覧)

サーバーワークス → 株式会社G-gen 執行役員CTO

2021 Japan APN Ambassadors / 2021 APN All AWS Certifications Engineers

マルチAWSアカウント管理運用やネットワーク関係のAWSサービスに関するブログ記事を過去に執筆。

2021年09月から株式会社G-genに出向、Google Cloud(GCP)が専門に。G-genでもGoogle Cloud (GCP) の技術ブログを執筆中。