技術一課の杉村です。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) の技術ブログを執筆中。