🦓

SSHポートフォワーディングとssm経由でDBクライアントツールを使う方法

2024/05/30に公開

はじめに

開発や検証環境での動作確認に伴ってDBに反映されたかどうかを確認したい時があります。
実務ではセッションマネージャーを使用しDBクライアントツール経由でRDSエンドポイントに接続してます。
そのため、AWS関連のツールインストール・設定を行う必要があるのてそちらのやり方についてまとめてみました。macOSでの手順になります。

SSHポートフォワーディングとは

SSHポートフォワーディングとは、SSHを使用してネットワークトラフィックを転送する仕組みです。これにより、直接アクセスできないサーバーやサービスに、安全な暗号化トンネルを通じてアクセスすることができます。

  1. ローカルフォワーディング(-L):ローカルマシンのポートからリモートサーバーへトンネルを作成
ssh -L ローカルポート:リモートホスト:リモートポート ユーザー名@SSHサーバー
  1. リモートフォワーディング(-R):リモートサーバーのポートからローカルマシンへトンネルを作成
ssh -R リモートポート:ローカルホスト:ローカルポート ユーザー名@SSHサーバー

基本概念

  • RDSデータベースは通常、プライベートサブネット内にあり(インターネットから直接アクセス不可)
  • Session Managerを使って、クライアントマシンとプライベートサブネットのEC2踏み台サーバーの間にSSHトンネルを構築します
  • SSHトンネルで、DBクライアントツールからRDSデータベースに安全な接続を作成します

接続の流れ:

ローカルマシン -> セッションマネージャー -> EC2ホスト -> ポートフォワーディング -> RDSエンドポイント

この方法の利点:

  • RDSインスタンスをプライベートサブネットに保持できる
  • すべてのトラフィックがSSHトンネルで暗号化される
  • RDSインスタンスをインターネットに公開する必要がない

前提

  • EC2のセキュリティグループが作成され、インバウンドルールのSSH接続が許可されている
  • CLI経由でEC2への接続が許可されている
  • EC2に接続するIAMポリシーが作成&アッタチされていること

tl:dr;

  1. SSH鍵の発行と公開鍵の登録
  2. AWS CLIのインストール&設定
  3. IAMユーザーの認証情報を設定
  4. Session Managerプラグインをインストール&設定
  5. AWS Vaultをインストール
  6. SSHポートフォワーディングの設定を行う
  7. DBクライアントツールからRDSへ接続する

1. SSHアクセスキーを設定する

ssh-keygen -t rsa -b 4096 -C "" -f ~/.ssh/鍵ファイル名(任意)
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/***/.ssh/鍵ファイル名
Your public key has been saved in /Users/***/.ssh/鍵ファイル名.pub
The key fingerprint is:
SHA256:C+X7jhSs/6Y0CNPVEevoi11aFDh6uc1kyN1wnBSoVmw
The key's randomart image is:
+---[RSA 4096]----+
|         .ooo.   |
|         oE= .   |
|        =+= +    |
|     . BoB =     |
|    o +.S * .    |
|     o * @       |
|      o O =      |
|       * O.      |
|      . B=+      |
+----[SHA256]-----+

公開鍵をコピーします。

# 公開鍵をコピー
$ cat .ssh/xxx.pub
$ pbcopy < ~/.ssh/xxx.pub

AWSマネージメントコンソールへ移動し、
コンソール画面右上の自分のメールアドレスを押下 > セキュリティ認証情報をクリックします。

AWSCodeCommit認証情報タブを開き、SSH 公開キーのアップロードをクリックします。

モーダルないに公開鍵を貼り付けます。

2. AWS CLIのインストール&設定

続いて、AWS CLIのインストールと設定を行います。

curl コマンドを使用して、ファイルをダウンロードします

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 38.9M  100 38.9M    0     0  16.8M      0  0:00:02  0:00:02 --:--:-- 16.8M

ダウンロードした .pkg ファイルをソースとして指定して、標準の macOS installer プログラムを実行します。

sudo installer -pkg AWSCLIV2.pkg -target /
Password:
installer: Package name is AWS Command Line Interface
installer: Installing at base path /
installer: The install was successful.

シェルが aws で $PATH コマンドを検索して実行できることを確認します。

which aws
/usr/local/bin/aws
aws --version
aws-cli/2.22.26 Python/3.12.6 Darwin/24.1.0 exe/x86_64

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

AWS CLIにIAMユーザーで接続するために、IAMユーザーの認証情報を設定します。

AWSコンソールに戻ってアクセスキーを作成します。
セキュリティ認証情報 > アクセスキーを作成 > ユースケース:コマンドラインインターフェイス (CLI)を選択し、「次へ」をクリックします。
「説明タグ値」を入力(任意)し、「アクセスキーを作成」をクリックします。
次の画面で作成されたアクセスキーを確認します。

3. IAMユーザーの認証情報を設定

ターミナルにてAWSの認証情報を追加します。

aws configure
AWS Access Key ID :<上で確認したaws_access_key_id>
AWS Secret Access Key :<上で確認したaws_secret_access_key>
Default region name [None]: ap-northeast-1
Default output format [None]: json

アクセスキーが追加されたことを確認します。

cat ~/.aws/credentials
[default]
aws_access_key_id = ****************
aws_secret_access_key = ****************

configファイルを設定します。
チーム開発の場合、複数アカウント間でのアクセスを管理するため、IAMロールをAssumeしてEC2やRDSへアクセスするようにします。IAMユーザーに直接的な権限付与より安全です。

$ vi ~/.aws/config (以下を貼り付け)
[default]
output=json
region=ap-northeast-1
mfa_serial=arn:aws:iam::<IAMユーザーアカウントID>:mfa/<IAMユーザー名>

[profile <プロフィール名を任意で設定>]
role_arn=arn:aws:iam::<IAMロールID>:role/<IAMロール名>
source_profile=default
mfa_serial=arn:aws:iam::<IAMユーザーアカウントID>:mfa/<IAMユーザー名>
role_session_name=<IAMユーザー名>@<IAMユーザーアカウントID>

IAMロールを「Assume(引き受ける)」することによって、一時的な認証情報(Temporary credentials)を取得して、そのロールに付与された権限を一時的に使用できるようになります。

使用シーン:

  1. IAMユーザーとしてログインしている
  2. そのユーザーには直接EC2やRDSへのアクセス権限がない
  3. しかし、EC2やRDSにアクセスできる権限を持つロールを「Assume」する権限は持っている
  4. そのロールをAssumeすることで、一時的にEC2やRDSにアクセスできるようになる
IAMユーザー -> AssumeRole API呼び出し -> 一時的な認証情報を取得 -> その認証情報を使ってAWSリソースにアクセス

config情報が追加されたことを確認します。

cat ~/.aws/config

https://zenn.dev/frusciante/articles/28cd351fe9de60

4. Session Managerをインストールする

Session ManagerはAWSのSystems Manager(SSM)の機能の一つ、EC2インスタンスに対して、SSHポートを開放せずにセキュアな接続を提供するサービスです。ブラウザベースのシェルアクセスや、CLIを通じた接続が可能です。

バンドルされたインストーラをダウンロードします。

# Appleシリコン搭載のMac
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac_arm64/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3669k  100 3669k    0     0   363k      0  0:00:10  0:00:10 --:--:--  464k

パッケージを解凍します。

unzip sessionmanager-bundle.zip
Archive:  sessionmanager-bundle.zip
   creating: sessionmanager-bundle/
  inflating: sessionmanager-bundle/install
   creating: sessionmanager-bundle/bin/
  inflating: sessionmanager-bundle/bin/session-manager-plugin
  inflating: sessionmanager-bundle/seelog.xml.template
  inflating: sessionmanager-bundle/LICENSE
 extracting: sessionmanager-bundle/VERSION
  inflating: sessionmanager-bundle/THIRD-PARTY
  inflating: sessionmanager-bundle/RELEASENOTES.md
  inflating: sessionmanager-bundle/NOTICE
  inflating: sessionmanager-bundle/README.md

インストールコマンドを実行します。

sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
Password:
Creating install directories: /usr/local/sessionmanagerplugin/bin
Creating Symlink from /usr/local/sessionmanagerplugin/bin/session-manager-plugin to /usr/local/bin/session-manager-plugin
Installation successful!

Session Manager プラグインが正常にインストールされたことを確認するには、次のコマンドを実行します。

session-manager-plugin

インストールが成功すると、次のメッセージが返されます。

The Session Manager plugin is installed successfully. Use the AWS CLI to start a session.

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/install-plugin-macos-overview.html

Session Managerの設定を行います。

$ vi ~/.ssh/config (以下を貼り付け)
# SSH over Session Manager
host i-* mi-*
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

# 確認
$ cat ~/.ssh/config

i-*mi-* はインスタンスIDのパターンです:

  • i-*:EC2インスタンスID(例:i-1234567890abcdef0)にマッチ
  • mi-*:EC2マネージドインスタンスID(例:mi-1234567890abcdef0)にマッチ

ProxyCommandコマンドはSession Managerを通じてSSH接続のプロキシを設定しています:

  • %h:ホスト(インスタンスID)に置き換えられる
  • %p:ポート番号に置き換えられる
  • AWS-StartSSHSession:SSH接続用の特別なSSMドキュメントタイプ
  • AWS Systems Managerを通じて接続を確立する

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html

5. AWS Vaultをインストール

AWS VaultはAWSの認証情報を安全に管理するためのツールです。
アクセスキーを暗号化して保存し、必要な時だけ復号化して使用されます。
複数のAWSプロファイルを安全に管理し、切り替えたい場合便利です。

つまり、AWS Vaultは:

  1. セキュリティを向上させながら
  2. AWS認証情報の管理を簡単にし
  3. 特にSession ManagerやIAMロールと組み合わせて使う時に便利なツール
    という位置づけです。
brew install --cask aws-vault
...
==> Installing Cask aws-vault
==> Linking Binary 'aws-vault' to '/opt/homebrew/bin/aws-vault'
🍺  aws-vault was successfully installed!

認証情報を追加する。IAMで払い出したアクセスキーをaws-vaultに登録します。

aws-vault add <プロフィール名>
Enter Access Key ID: ****************************************
Enter Secret Access Key: ****************************************
Added credentials to profile "<プロフィール名>" in vault

Credentialsにプロフィールが設定されていることを確認します。

$ aws-vault ls
Profile                  Credentials              Sessions
=======                  ===========              ========
default                  default                  -
<プロフィール名>            -                        -

6. SSHポートフォワーディングの設定を行う

aws-vault exec (.aws/configに設定しているprofile名を入力) -- ssh -i ~/.ssh/鍵ファイル名 -N -L<ポート番号>:(DBエンドポイント):<ポート番号> (IAMユーザー名)@(インスタンスID)

DBエンドポイントとポート番号はRDSから確認できます。
インスタンスIDはEC2から確認できます。

成功すると以下のメッセージが表示され、MFAコードを入力して実行します。

Enter MFA code for arn:aws:iam::********:mfa/********:

7. DBクライアントツールからRDSへ接続する

  • Name: 任意の識別しやすい名前
  • Host: 「localhost」を入力
  • Username: マスターユーザー名を入力(AWSのRDSから確認)
  • Password: RDSのパスワード
  • Database: DB 名を入力(AWSのRDSから確認)
  • Port: ポート番号を入力

DBに接続します。

終わりに

セッションマネージャーを使用し踏み台サーバーを経由しDBに接続するためのAWS関連のツールインストール・設定をまとめてみました。
誰かの参考になれば嬉しいです。

Discussion