AWS SSM(Systems Manager)のポートフォワーディング機能を使えば、SSH接続もセキュリティグループの22番開放も不要で、プライベートサブネット内のリソースへローカルポート経由でアクセスできます。しかし「コマンドは知っているがIAMポリシーの最小権限設定がわからない」「VPCエンドポイントが足りなくて接続できない」という声をよく聞きます。
この記事では、
aws ssm start-session --document-name AWS-StartPortForwardingSession をプライベートサブネット設計に組み込む手順と、最小権限を守るIAMポリシーの構成パターンを解説します。Amazon Linux 2023 / RHEL 9.4で動作確認済みです。この記事のポイント
・aws ssm start-session でプライベートサブネットのRDS/Redisにローカル接続できる
・VPCエンドポイントは ssm・ssmmessages・ec2messages の3本が必要
・IAMポリシーはドキュメント名とインスタンスIDをResourceで限定して最小権限にする
・セキュリティグループの22番・3306番・5432番の受信ルールは不要になる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜSSMポートフォワーディングなのか
プライベートサブネットのEC2にSSHで入るには、パブリックサブネットに踏み台を立てるのが従来の手法です。しかし踏み台には「EC2コスト・管理負荷・22番ポートの外部公開」という三重のコストがかかります。SSMポートフォワーディングは、EC2インスタンスにインストールされたSSM Agentがマネジメントコンソール側から通信を引っ張る仕組みです。インスタンスへの受信ポートは一切開ける必要がありません。通信経路はSSMのVPCエンドポイント経由でAWS内部に閉じるため、パブリックIPもインターネットゲートウェイも不要になります。
VPCとプライベートサブネット設計の基礎からおさらいしたい方は、AWS Amazon Linuxの実践セミナーでVPCアーキテクチャの「型」を体系的に学ぶことができます。
事前準備:VPCエンドポイントとIAMポリシー
1. 必要なVPCエンドポイント3本を確認する
インターネットゲートウェイを持たないプライベートサブネットでSSMを動かすには、以下の3本のインターフェース型VPCエンドポイントが必須です。・com.amazonaws.ap-northeast-1.ssm:セッション制御チャネル
・com.amazonaws.ap-northeast-1.ssmmessages:セッションデータ転送チャネル
・com.amazonaws.ap-northeast-1.ec2messages:Run Command/Patch Manager共用
作成済みかどうかは次のコマンドで確認できます。
# VPCエンドポイントの一覧を確認する $ aws ec2 describe-vpc-endpoints --filters "Name=vpc-id,Values=vpc-0a1b2c3d4e5f67890" --query 'VpcEndpoints[*].{Service:ServiceName,State:State}' --output table ------------------------------------------------------------------------------------------- | DescribeVpcEndpoints | +-----------+-----------------------------------------------------------------------------+ | State | Service | +-----------+-----------------------------------------------------------------------------+ | available| com.amazonaws.ap-northeast-1.ec2messages | | available| com.amazonaws.ap-northeast-1.ssm | | available| com.amazonaws.ap-northeast-1.ssmmessages | +-----------+-----------------------------------------------------------------------------+
available であることを確認します。1本でも欠けるとSSMセッションが確立できません。また、各エンドポイントのセキュリティグループで、EC2インスタンスのセキュリティグループからの443番(HTTPS)インバウンドを許可してください。2. IAMポリシーをポートフォワーディング専用に絞る
ポートフォワーディング専用の最小権限ポリシーは次のとおりです。AmazonSSMManagedInstanceCore を丸ごと付けるのではなく、実行できるドキュメントとターゲットインスタンスをResourceで限定します。{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowPortForwarding", "Effect": "Allow", "Action": "ssm:StartSession", "Resource": [ "arn:aws:ec2:ap-northeast-1:123456789012:instance/i-0123456789abcdef0", "arn:aws:ssm:ap-northeast-1::document/AWS-StartPortForwardingSession", "arn:aws:ssm:ap-northeast-1::document/AWS-StartPortForwardingSessionToRemoteHost" ] }, { "Sid": "AllowSessionManagement", "Effect": "Allow", "Action": [ "ssm:TerminateSession", "ssm:ResumeSession", "ssm:DescribeSessions", "ssm:GetConnectionStatus" ], "Resource": "arn:aws:ssm:*:*:session/-*" } ] }
・ssm:StartSession の Resource にインスタンスARNとドキュメントARNを並記する。これをしないと「AccessDeniedException」が出る
・ssm:TerminateSession の Resource に
-* を付けると、他ユーザーのセッションを誤って終了させるリスクを防げるなお、EC2インスタンス側のIAMロールには
AmazonSSMManagedInstanceCore が必要です(SSM AgentがSSMサービスへ登録するため)。aws ssm start-sessionでポートフォワーディングを実行する
1. 基本コマンドとパラメータ
ポートフォワーディングのコマンド書式は次のとおりです。# ローカルの15432番をEC2経由でRDS(5432番)へ転送する $ aws ssm start-session --target i-0123456789abcdef0 --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["5432"],"localPortNumber":["15432"]}' Starting session with SessionId: tomohiro-0a1b2c3d4e5f67890 Port 15432 opened for sessionId tomohiro-0a1b2c3d4e5f67890. Waiting for connections...
psql -h 127.0.0.1 -p 15432 -U postgres mydb のように接続します。--target にはSSM Agentが動いているEC2インスタンスIDを指定します。RDS自体はSSM管理対象外なので、プライベートサブネット内の中継EC2を経由させる設計が基本です。RDSへの直接ポートフォワーディングには AWS-StartPortForwardingSessionToRemoteHost ドキュメントを使います(後述)。2. RDSへの直接ポートフォワーディング(RemoteHost指定)
EC2をポートフォワーディングの中継点にしつつ、接続先ホスト名をRDSエンドポイントへ向ける方法がAWS-StartPortForwardingSessionToRemoteHost です。EC2にデータベースクライアントを入れる必要がなくなります。# EC2(i-0123456789abcdef0)経由でRDSエンドポイントの5432番に転送する $ aws ssm start-session --target i-0123456789abcdef0 --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{ "host":["mydb.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com"], "portNumber":["5432"], "localPortNumber":["15432"] }' Starting session with SessionId: tomohiro-0b2c3d4e5f678901 Port 15432 opened for sessionId tomohiro-0b2c3d4e5f678901. Waiting for connections...
ss -tlnp や lsof -i :15432 で15432番がLISTEN状態になっていれば正常です(Linux ポート確認の全コマンド)。3. セッションを安全に終了する
# 実行中のセッションIDを確認する $ aws ssm describe-sessions --state Active --query 'Sessions[*].{ID:SessionId,Target:Target,Start:StartDate}' --output table --------------------------------------------------------------------------- | DescribeSessions | +--------------------------------------+-----------------+----------------+ | ID | Start | Target | +--------------------------------------+-----------------+----------------+ | tomohiro-0b2c3d4e5f678901 | 2026-10-11T.. | i-01234... | +--------------------------------------+-----------------+----------------+ # セッションを終了する $ aws ssm terminate-session --session-id tomohiro-0b2c3d4e5f678901 { "SessionId": "tomohiro-0b2c3d4e5f678901" }
terminate-session でサーバー側から明示的に切断するほうがCloudTrailログに終了記録が残り、監査対応がしやすくなります。プライベートサブネット設計への組み込み方
SSMポートフォワーディングをプライベートサブネット設計に組み込む際のセキュリティグループ設計を整理します。EC2インスタンスのセキュリティグループ(アウトバウンドのみ):
・443(HTTPS)→ VPCエンドポイントのセキュリティグループ:必須
・22(SSH):不要(インバウンドは一切開けない)
RDS/ElastiCacheのセキュリティグループ:
・5432/3306/6379 → EC2のセキュリティグループ:EC2からのインバウンドのみ許可
・インターネット側からの受信ルールは一切不要
この設計により、外部からの直接攻撃面は実質ゼロになります。接続経路はSSMのTLS通信に一本化され、CloudTrailでユーザーごとのアクセス履歴を追跡できます。
マルチAZ設計でActive/StandbyのEC2が複数ある場合、IAMポリシーの
ssm:StartSession のResourceをインスタンスARNではなくタグ条件に変えることで、自動フェイルオーバー後も同じポリシーで接続できます。# タグ条件でポートフォワーディングを許可する例(マルチAZ対応) { "Effect": "Allow", "Action": "ssm:StartSession", "Resource": "arn:aws:ec2:ap-northeast-1:123456789012:instance/*", "Condition": { "StringEquals": { "ssm:resourceTag/Env": "prod", "ssm:resourceTag/Role": "ssm-bastion" } } }
ssm:resourceTag 条件キーにより、タグ Env=prod かつ Role=ssm-bastion が付いたインスタンスにのみポートフォワーディングを限定できます。トラブルシュート:接続できない時の確認手順
「An error occurred (TargetNotConnected)」が出るEC2インスタンス上のSSM Agentが停止しているか、VPCエンドポイントが不足しています。インスタンス内で
systemctl status amazon-ssm-agent を確認し、停止していれば systemctl start amazon-ssm-agent で起動します。VPCエンドポイントの3本セットが揃っているかも再確認してください。「AccessDeniedException」が出る
IAMポリシーのResource指定が不完全です。
ssm:StartSession のResourceにインスタンスARNとドキュメントARNの両方を記載しているか確認してください。「arn:aws:ssm:region::document/AWS-StartPortForwardingSession」の形式でリージョンとアカウントIDの間にコロンが2つ(::)あることに注意です。ローカルポートには繋がるがDB接続がタイムアウトする
RDSのセキュリティグループが中継EC2からのインバウンドを許可していない可能性があります。RDSのセキュリティグループで「インバウンド→EC2のセキュリティグループID→ポート5432」を確認してください。
本記事のまとめ
| やりたいこと | コマンド・設定 |
|---|---|
| EC2経由でRDS(5432番)にローカル転送 | aws ssm start-session --target i-xxx --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["5432"],"localPortNumber":["15432"]}' |
| RDSエンドポイントへ直接ポートフォワード | aws ssm start-session --target i-xxx --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["rds-endpoint"],"portNumber":["5432"],"localPortNumber":["15432"]}' |
| IAM最小権限:ドキュメント限定 | Resource に インスタンスARN と AWS-StartPortForwardingSession ドキュメントARNを並記 |
| マルチAZ対応:タグ条件で絞る | Condition に ssm:resourceTag/Env + ssm:resourceTag/Role を設定 |
| VPCエンドポイント確認 | aws ec2 describe-vpc-endpoints で ssm / ssmmessages / ec2messages の3本を確認 |
| セッション強制終了 | aws ssm terminate-session --session-id セッションID |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:AWS SSM Documentで冗長構成を自動化する方法|複数AZへの統一手順適用
- この記事の属するカテゴリ:AWS(Amazon Linux)へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます