リモートワークが広く普及し、自宅からEC2へ接続したいという要件が多くなってきました。
その際に問題になるのは、SSHのセキュリティグループのルールをどのように設定するかだと思います。
IPが変動する場合、セキュリティグループのソースにIPを指定することができません。
そこで、IAMユーザによる認証でEC2へ接続することが可能な、Session Managerを利用しVPC内のリソースへアクセスする方法をご紹介します。

要件

今回は、下記の要件を満たすことを目的として、Session Managerの利用方法を紹介します。

  • アクセス許可したいEC2は2台
  • SFTPを利用したい
  • RDS(プライベート)への接続をしたい

構成

EC2とRDSへのアクセスは、SSMのポートフォワーディング機能を利用してアクセスします。

準備

EC2インスタンスのセットアップ

セッションマネージャを利用するには、SSM Agentがインスタンスにインストールされている必要があります、
AmazonLinux2にはデフォルトでインストールされているますが、Agentのアップデートが必要な場合があります。
その他のOSでは手動でインストールする必要があります。
下記公式リファレンスから、任意のOSのインストール手順を参照してください。
参考:Linux 用 EC2 インスタンスに手動で SSM Agent をインストールする

Agentのインストールが完了したら、EC2のロールにAmazonSSMManagedInstanceCoreポリシーをアタッチします。

セッションマネージャの詳しい利用条件:ステップ 1: Session Manager の前提条件を満たす

IAMユーザの払い出し

SSMでEC2にアクセスできるように、IAMポリシーを付与します。
参照:クイックスタート Session Manager のエンドユーザーポリシー(セッションマネージャ and CLI)

今回、SFTPとRDSへの接続をポートフォワーディングで実現するため、下記のドキュメントへのアクセスを追加します。

"arn:aws:ssm:region::document/AWS-StartPortForwardingSession"
"arn:aws:ssm:region::document/AWS-StartPortForwardingSessionToRemoteHost"

リファレンスには下記のコンディションがssm:StartSessionアクションに追加されていますが、使用するドキュメントを制限しなければ省略可能です。

"Condition": {
"BoolIfExists": {
"ssm:SessionDocumentAccessCheck": "true"
}
}

kms:GenerateDataKeyアクションの許可は、KMSを使用しないため削除しています。

最終的に下記ポリシーをIAMユーザへアタッチします。

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": [
"arn:aws:ec2:region:123456789012:instance/任意のインスタンスID",
"arn:aws:ec2:region:123456789012:instance/任意のインスタンスID",
"arn:aws:ssm:region::document/SSM-SessionManagerRunShell",
"arn:aws:ssm:region::document/AWS-StartPortForwardingSession",
"arn:aws:ssm:region::document/AWS-StartPortForwardingSessionToRemoteHost"
],
},
{
"Effect": "Allow",
"Action": [
"ssm:DescribeSessions",
"ssm:GetConnectionStatus",
"ssm:DescribeInstanceProperties",
"ec2:DescribeInstances"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:TerminateSession",
"ssm:ResumeSession"
],
"Resource": [
"arn:aws:ssm:*:*:session/${aws:username}-*"
]
}
]
}

接続

コンソールアクセス

EC2へコンソールアクセスする場合は、下記コマンドで接続します。

aws ssm start-session --target {対象のインスタンスID}

--document-nameを省略した場合、SSM-SessionManagerRunShellがデフォルトで使用されます。
そのため、EC2内へのコンソールアクセスでは--document-nameの指定は不要です。

SFTP接続

22番ポートをポートフォワーディングし、ホストにローカルホストを指定してSFTP接続ができます。

SSMで接続したホストに対してポートフォワーディングする場合は、AWS-StartPortForwardingSessionドキュメントを使用します。

aws ssm start-session --target 対象のインスタンスID --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["22"], "localPortNumber":["2200"]}'

~~
~~

n-nakatani@n-nakatani3::~$ sftp -oPort="2200" -i .ssh/key/private_key.pem ec2-user@localhost
Connected to localhost.
sftp>

RDS接続

SSMで接続したホスト経由で、別のホストにアクセスする場合は、AWS-StartPortForwardingSessionToRemoteHostを使用します。

EC2インスタンス経由でRDSへポートフォワーディングし、mysqlコマンドの接続先ホストを127.0.0.1にしてRDSへ接続できます。

aws ssm start-session --target 対象のインスタンスID --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"portNumber":["3306"], "localPortNumber":["33060"], "host":["RDSのホスト名"]

~~
~~

n-nakatani@n-nakatani3::~$ mysql -h 127.0.0.1 -P 33060 -u admin -p --ssl-mode=DISABLED
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 242562
Server version: 5.7.17-log MySQL Community Server (GPL)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

SSH接続

SSM-SessionManagerRunShellで接続した場合、ssm-userでEC2へログインされます。
ssm-userでログインさせない場合や、SSM経由でSSHで接続させたい場合は下記の設定で対応することができます。
参考:(オプション) Session Manager を通して SSH 接続のアクセス許可を有効にして制御する

ssm:StartSessionアクションでAWS-StartSSHSessionドキュメントへの許可が必要になるので、ポリシーに追記する必要があります。
SSHログインのみに制限したい場合は、ssm:StartSessionアクションのResourceからSSM-SessionManagerRunShellドキュメントを削除し、下記Conditionを追加する必要があります。

"Condition": {
"BoolIfExists": {
"ssm:SessionDocumentAccessCheck": "true"
}
}

SSM-SessionManagerRunShellのアクセス制御が少し特殊で、aws ssm start-sessionコマンドを使用すると--document-nameがない場合、SSM-SessionManagerRunShellをデフォルトで使用し、明示的なドキュメントの指定がなくてもこのドキュメントへアクセスが可能になっています。
Conditionを付与することで、--document-nameを付与する必要があり、明示的なアクセスが無いドキュメントは使用できなくなります。

まとめ

SSMのみでEC2への接続だけでなく、RDSやRDPなど別のホストにアクセスすることができます。
SSM Agentをインストールすることで、インスタンスの接続だけでなくパッケージ管理やアカウント管理をすることも可能です。
インスタンスの運用保守の観点からも、SSMの導入はおすすめです。