はじめに
AWSのセキュリティベストプラクティスにおいて、データベース(RDS)はパブリックサブネットではなく、インターネットから直接アクセスできないプライベートサブネットに配置することが鉄則です。しかし、開発作業やメンテナンス時に、ローカルPCからデータベースへ直接接続してデータを直接確認したいケースは多々あります。
従来は踏み台サーバー(Bastion)をパブリックサブネットに起動し、SSHトンネル(ポートフォワーディング)を利用するのが一般的でした。しかし、この方法ではSSHキーの管理や、踏み台サーバー自体の脆弱性管理、22番ポートの開放など、セキュリティ上の運用負荷が発生します。
そこで、本記事ではAWS Systems Manager(SSM)の「Session Manager」と「ポートフォワーディング」機能を活用し、踏み台サーバーのSSHポートを開放することなく、安全にローカルPCからプライベートサブネット内のRDSに接続する手順を解説します。
前提知識/必要な理由
この構成を採用する最大の理由は、「安全性の向上」と「管理コストの削減」です。SSMポートフォワーディングを使用することで、以下のメリットが得られます。
- 踏み台サーバーのインバウンドポート(22番や3389番)を完全に閉鎖できるため、不正アクセスのリスクを極限まで低減できます。
- IAMによる細かなアクセス制御が可能になり、「誰が」「いつ」接続したかのログをCloudTrailで管理・監査できます。
- SSHキーの管理が不要になり、メンバーの退職やキーの紛失に伴うローテーションの手間がなくなります。
構成概要
ローカルPCからAWS CLIを使用してSSM経由で踏み台EC2インスタンス(※SSMエージェントのみが起動しているプライベートなインスタンス)に接続し、そのインスタンスを経由してプライベートRDSにトラフィックを転送(ポートフォワード)します。
具体的な設定手順・設計方法
1. ローカルPCの事前準備(AWS CLIとSSMプラグインの導入)
SSMポートフォワーディングを実行するには、ローカルPCに「AWS CLI」と「Session Manager Plugin」が必要です。以下はmacOS(Homebrew)およびWindowsでの導入手順です。
macOSの場合:
# AWS CLIのインストール
brew install awscli
# Session Manager Pluginのインストール
brew install --cask session-manager-plugin
Windows(PowerShell)の場合:
# AWS CLIのインストール(インストーラーのダウンロード)
Start-Process "https://awscli.amazonaws.com/AWSCLIV2.msi" -Wait
# Session Manager Pluginのインストール(インストーラーのダウンロード)
Start-Process "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/windows_amd64/SessionManagerPluginSetup.exe" -Wait
※インストール後、ターミナルまたはPowerShellを再起動し、session-manager-pluginコマンドが実行できることを確認してください。
2. 踏み台EC2インスタンスの作成とIAMロールの付与
プライベートサブネットに踏み台となるEC2インスタンスを起動します。このインスタンスはインターネットから直接アクセスされる必要がないため、パブリックIPは不要です。
ステップ A: IAMロールの作成
EC2がSystems Managerと通信できるように、IAMロールを作成して付与します。
- 信頼されたエンティティ:EC2
- 許可ポリシー:AmazonSSMManagedInstanceCore
ステップ B: セキュリティグループの設定
セキュアな接続を保つため、セキュリティグループの設定は最小限にします。
- 踏み台EC2のセキュリティグループ(SG-Bastion): インバウンドルールはすべて空(許可ルールなし)にします。アウトバウンドはインターネット方向(HTTPS/443ポート)を開放します(SSMエンドポイントとの通信のため)。
- RDSのセキュリティグループ(SG-RDS): インバウンドルールに、SG-BastionからのDBポート(例: PostgreSQLなら5432)のみを許可します。
3. SSMポートフォワーディングの実行
準備が整ったら、ローカルPCのターミナルから以下のコマンドを実行してポートフォワーディングを開始します。ここではローカルのポート「15432」を踏み台EC2(インスタンスID: i-xxxxxxxxxxxxxxxxx)経由でRDSの「5432」ポートに転送します。
aws ssm start-session \
--target i-xxxxxxxxxxxxxxxxx \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["my-rds-database.xxxxxx.ap-northeast-1.rds.amazonaws.com"],"portNumber":["5432"],"localPortNumber":["15432"]}'
コマンド実行後、Starting session with SessionId: ... と表示されれば接続待機状態になります。ターミナルは閉じずにそのままにしておきます。
4. データベースクライアントからの接続確認
任意のデータベースクライアントツール(DBeaver、pgAdminなど)を開き、接続情報を以下のように設定して接続します。
- ホスト名(Host): localhost (または 127.0.0.1)
- ポート(Port): 15432(上記コマンドで指定したlocalPortNumber)
- データベース名/ユーザー名/パスワード: RDSの設定値
実務での注意点
- セッションのタイムアウト: SSM Session Managerはデフォルトでアイドル状態が続くとセッションが切断されます。必要に応じてSSMのコンソールから「最大セッション時間」の設定を調整してください。
- VPCエンドポイントの検討: 踏み台EC2が完全なプライベートサブネット(NATゲートウェイもなし)にある場合、SSMのAPIと通信するために、VPC内にSSM用のインターフェースVPCエンドポイント(ssm, ssmmessages, ec2messages)を構築する必要があります。
- IAMポリシーの制限: 開発者にポートフォワーディングを許可する場合は、IAMポリシーで
ssm:StartSessionの実行権限を対象のインスタンスやリソースに限定し、最小権限の原則を徹底してください。
まとめ
SSM Session Managerを使用したポートフォワーディングは、踏み台サーバーの運用コストとセキュリティリスクを劇的に下げることができる、現代のAWSインフラ設計における必須テクニックです。鍵管理の煩わしさから解放され、監査ログも一元管理できるため、実務で積極的に導入を検討してください。