SSMポートフォワーディングを使用してローカルのSSMSからRDS for SQL Serverに接続してみた
SSMポートフォワーディングを使用してローカルのSSMSからRDS for SQL Serverに接続してみた
どうもさいちゃんです。
皆さんプライベートサブネットにあるRDS for SQL Serverを使用する場合、どのようにDBへ接続をしていますか?
例えば、以下のような方法を使っている方が多いのではないでしょうか?
- 踏み台サーバー上にSSMSをインストールして接続する
- 拠点とVPC間をVPNやDirect Connectで接続し、ローカルPCのSSMSからアクセスする
SSMのポートフォワーディングを使用することでローカルのSSMSを使用してEC2経由でRDSにアクセスすることが可能なんじゃないかと思い、実際に検証してみることにしました。
検証構成
今回は下記のような構成で検証を行ないます。
ローカルのSSMSを使用してRDSへポートフォワーディング経由でアクセスをしますが、RDSにはSSMエージェントをインストールできないのでEC2を経由する形になります。

各インスタンスの詳細情報については下記に記載します。
前提条件
インフラストラクチャ
| リソース | 仕様 | 配置 |
|---|---|---|
| EC2 | Windows Server 2022( t3.medium) | プライベートサブネット |
| RDS | SQL Server 2022 16.00.4215.2.v1(db.t3.micro) | プライベートサブネット |
必要なツール
| ツール | 用途 |
|---|---|
| AWS CLI | SSM Session Managerの実行 |
| Session Manager Plugin | SSMポートフォワーディングの実行 |
| SSMS | SQL Serverへの接続 |
IAM権限
| リソース | 必要な権限 | 用途 |
|---|---|---|
| EC2インスタンス | SSMアクセス権限(AmazonSSMManagedInstanceCore) | SSM Session Manager経由での接続 |
| RDSインスタンス | S3統合用のIAMロール | S3へのバックアップ/復元を行う場合。設定手順は下記に記載 |
| ローカルPC | EC2/RDS/S3へのアクセス権限 | AWS CLI経由での操作 |
セキュリティグループ設定
EC2のセキュリティグループ
インバウンドルール
- 無し
アウトバウンドルール
| タイプ | プロトコル | ポート範囲 | 送信先 | 説明 |
|---|---|---|---|---|
| All traffic | All | All | 0.0.0.0/0 | 全開放 |
今回はEC2に対してはSSMのポートフォワーディング経由でのアクセスのため、インバウンドは開ける必要はありません。
アウトバウンドに関しても検証のため全開放としていますが、SQL Serverへの1433ポートとSSM用に443ポートが空いていれば問題ないです。
RDSのセキュリティグループ (sg-0b73c233459d2b0ac: rds-sg)
インバウンドルール
| タイプ | プロトコル | ポート範囲 | 送信元 | 説明 |
|---|---|---|---|---|
| Custom TCP | TCP | 1433 | EC2のセキュリティグループ | EC2からのSQL Server接続 |
アウトバウンドルール
| タイプ | プロトコル | ポート範囲 | 送信先 | 説明 |
|---|---|---|---|---|
| All traffic | All | All | 0.0.0.0/0 | 全開放 |
EC2のセキュリティグループからの1433ポートを許可しておきましょう。
やってみた
それではローカルPCから下記のコマンドを実行して1433をローカルの11433ポートにフォワードします。
aws ssm start-session `
--target i-xxxxxxxxxxxxxxxxx `
--document-name AWS-StartPortForwardingSessionToRemoteHost `
--parameters host="test-sqlserver.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com",portNumber="1433",localPortNumber="11433" `
--profile <プロファイル名>
実行結果:
Starting session with SessionId: botocore-session-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Port 11433 opened for sessionId botocore-session-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Waiting for connections...
この状態でローカルのSSMSを開き下記のように情報を埋めます。

- サーバーの種類:データベースエンジン
- サーバー名:
127.0.0.1,11433127.0.0.1:ローカルホスト(自分自身のPC)11433: SSMポートフォワーディングで設定したローカルポート番号- SSMポートフォワーディングにより、ローカルPCの11433ポートがRDSに転送されるため、ローカルホストを指定します
- 認証: SQL Server認証
- ログイン: RDSのマスターユーザー名
- パスワード: RDSのマスターパスワード
接続してみましょう。

ローカルのSSMSを使用してプライベートサブネット内のRDS for SQL Serverに接続することが出来ました。
接続が正常に動作するか、実際にデータ操作を行って確認してみます。
データを入れてみる
試しにテストデータを入れてみます。
テスト用のDBを作成してテストデータを20件ほど入れてみました。
CREATE DATABASE CustomerDB;
GO
-- サンプルテーブルの作成(顧客情報の例)
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY IDENTITY(1,1),
CompanyName NVARCHAR(100) NOT NULL,
ContactName NVARCHAR(50),
ContactTitle NVARCHAR(50),
Address NVARCHAR(200),
City NVARCHAR(50),
Region NVARCHAR(50),
PostalCode NVARCHAR(20),
Country NVARCHAR(50) DEFAULT 'Japan',
Phone NVARCHAR(20),
Email NVARCHAR(100),
CreatedDate DATETIME DEFAULT GETDATE(),
UpdatedDate DATETIME DEFAULT GETDATE(),
IsActive BIT DEFAULT 1
);
GO

データの格納は問題ないようです。
バックアップ&リストア
RDS for SQL Serverはネイティブバックアップを利用した復元が可能です。
今回はSSM経由でのストアドプロシージャなどがうまくいくのかについて確認してみたいと思います。
RDS for SQL ServerでS3へネイティブバックアップの保存やリストアを行いたい場合はオプショングループの設定が必要です。
適切な名前でオプショングループを作成します。

オプション名は「SQLSERVER_BACKUP_RESTORE」を選択しIAMロールを選択します。
すでに必要な権限をもったIAMロールを作成している場合はそちらを選択します。
今回はIAMロールを新たに作ります。

対象バケットと暗号化の有無を設定します。

自動作成されたIAMロールにアタッチされたポリシーの中身はこんな感じです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey"
],
"Resource": [
"arn:aws:kms:ap-northeast-1:<アカウントID>:key/xxxxxxxxxxxxxxxxxxxxxxxxxx"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::<バケット名>/backups/"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObjectMetaData",
"s3:GetObject",
"s3:PutObject",
"s3:ListMultipartUploadParts",
"s3:AbortMultipartUpload"
],
"Resource": [
"arn:aws:s3:::<バケット名>/backups/*"
]
}
]
}
上記で作成したオプショングループをRDSに関連付けます。

すぐに設定が適用されるようにして変更を確定します。

ではバックアップを行ってみます。
USE CustomerDB;
GO
EXEC msdb.dbo.rds_backup_database
@source_db_name = 'CustomerDB',
@s3_arn_to_backup_to = 'arn:aws:s3:::<バケット名>/backups/CustomerDB.bak',
@type = 'FULL',
@overwrite_s3_backup_file = 1;
GO
S3の方を確認するとしっかりバックアップファイルが保存されています。

リストアしてみましょう。
EXEC msdb.dbo.rds_restore_database
@restore_db_name = 'CustomerDB_Restored',
@s3_arn_to_restore_from = 'arn:aws:s3:::<バケット名>/backups/CustomerDB.bak',
@type = 'FULL',
@with_norecovery = 0;
GO
中身を確認してみましょう。
USE CustomerDB_Restored;
GO
SELECT * FROM Customers ORDER BY CustomerID;
GO

復元もうまくいっていることが確認できました。
まとめ
本記事では、SSMポートフォワーディングを使用してローカルのSSMSからプライベートサブネット内のRDS for SQL Serverに接続する方法を検証しました。
検証の結果、以下のことが確認できました
- SSMポートフォワーディング機能を使用することで、ローカルPCのSSMSからプライベートサブネット内のRDS for SQL Serverに接続可能
- RDSにはSSMエージェントをインストールできないため、EC2インスタンスを経由する構成が必要
- EC2のインバウンドルールを開ける必要がなく、SSM Session Manager経由で安全に接続可能
- データの投入、バックアップ、リストアなどの操作も問題なく実行可能
今回は大量のデータをいれるようなテストはしていないので、性能評価は必須ですが、従来の踏み台サーバーやVPN接続の代替手段として、SSMポートフォワーディングは有効な選択肢の一つかもしれないです。
特に、一時的な接続や開発環境での利用において、インフラの追加構築が不要な点とIAMベースのアクセス制御が可能な点がうれしいですね。








