継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

踏み台用 ECS Fargate から Aurora へのローカル接続を実現する

タダです.

AWSコンテナ設計・構築[本格]入門」を読んでて,ECS Fargate で踏み台を作るハンズオンがあります.この踏み台コンテナを使って Eureca さんの記事で紹介されてたローカルの DB クライアントからプライベートサブネットの Aurora へ socat で TCP リレーを行い接続する検証をしてみたのでやった作業をこの記事に書いていきます.

検証概要

自分の管理している環境では AWS SSO を採用して AWS アカウントにログインしています.また各システムアカウントには踏み台用 AWS アカウントを経由して更にスイッチロールでログインしており,開発者ごとに必要な権限を渡す運用にしています.

検証では踏み台コンテナに AWS SSO 経由で許可された開発者だけアクセスさせるようにしたいので,スイッチロールを行った後 Session Manager の AWS-StartPortForwardingSession を使ってローカルからプライベートサブネットの Aurora へ接続を試みます.

検証イメージ

f:id:sadayoshi_tada:20220203220318p:plain

必要なセットアップ

今回の検証を行うために次のツールのセットアップを行います.

AWS CLI v2 の導入後の確認

 % aws --version
aws-cli/2.2.11 Python/3.8.8 Darwin/19.6.0 exe/x86_64 prompt/off

Session Manager Plugin の導入後の確認

% session-manager-plugin

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

事前準備

事前準備として SSO 初期設定と AWS CLI の初期設定を行います.

AWS CLI 初期設定

1, ~/.aws/credentials のファイルに AWS SSO に表示されている踏み台 AWS アカウントのクレデンシャル情報を追記する

[踏み台 AWS アカウントの任意のプロファイル名]
aws_access_key_id=hoge
aws_secret_access_key=hoge
aws_session_token=hoge

[システム AWS アカウントの任意のプロファイル名]
role_arn = arn:aws:iam::12345678910:role/[スイッチロールのロール名]
source_profile = [踏み台 AWS アカウントの任意のプロファイル名]

2, ~/.aws/config のファイルに下記のように追記する

[profile システム AWS アカウントの任意のプロファイル名]
region = ap-northeast-1
output = json

SSO 初期設定

1, aws configure sso --profile [踏み台 AWS アカウントのプロファイル名] を実行してプロンプトに必要な情報を埋める

% aws configure sso --profile [踏み台 AWS アカウントのプロファイル名]
SSO start URL [None]: https://hoge.awsapps.com/start#/                                                         
SSO Region [None]: ap-northeast-1                                                                                         
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.ap-northeast-1.amazonaws.com/

Then enter the code:

hoge-hoge(自動で表示される)
There are 5 AWS accounts available to you.
Using the account ID 12345678910(踏み台 AWS アカウント)
There are 5 roles available to you.
Using the role name "hoge-role"(踏み台 AWS アカウントで使っているロール名)
CLI default client Region [None]: ap-northeast-1                                                                          
CLI default output format [None]: json                                                                                    

To use this profile, specify the profile name using --profile, as shown:

aws s3 ls --profile 12345678910_bastion-switch-role <=ここまで出れば終了

2, 以下のコマンドを実行し、システム AWS アカウントのスイッチロール先 IAM ロールが表示されたら完了

% aws --profile [システム AWS アカウントのプロファイル名]sts get-caller-identity
{
    "UserId": "hoge:botocore-session-123456789",
    "Account": "12345678910",
    "Arn": "arn:aws:sts::12345678910:assumed-role/switch-role/botocore-session-123456789"
}

クライアント側から接続のためのスクリプト

DB クライアント側から接続するために開発者が実行する共通処理をスクリプトにしてみました.

#!/bin/sh
# RDS のホスト名
TARGET_HOST=hoge.ap-northeast-1.rds.amazonaws.com
# ターゲットのポート番号
PORT_NUBMER=3306
# ローカルのポート番号
LOCAL_PORT_NUMBER=3306
# 踏み台 AWS アカウントのプロファイル名
SOURCE_PROFILE=[踏み台 AWS アカウントのプロファイルを記載]
# システム AWS アカウントのプロファイル名
SYSTEM_PROFILE=[システム AWS アカウントのプロファイルを記載]

# init
aws sso login --profile ${SOURCE_PROFILE}

# オンラインステータスのコンテナIDを取得
BASTION_CONTAINER_ID=`aws --profile ${SYSTEM_PROFILE} ssm describe-instance-information --filters "Key=PingStatus,Values=Online" | jq -r '.InstanceInformationList[] | select ( .InstanceId| startswith("mi-")) | .InstanceId '`

# コマンドID取得
COMMAND_ID=`aws --profile ${SYSTEM_PROFILE} ssm send-command \
  --instance-ids ${BASTION_CONTAINER_ID} \
  --document-name [socat 実行するためのドキュメント名] \
  --parameters targetHost=${TARGET_HOST} | jq -r .Command.CommandId`

# ポートフォワード
aws --profile ${SYSTEM_PROFILE} ssm start-session \
    --target ${BASTION_CONTAINER_ID} \
    --document-name AWS-StartPortForwardingSession \
    --parameters portNumber=${PORT_NUBMER},localPortNumber=${LOCAL_PORT_NUMBER}

# RunCommand のキャンセル
aws --profile ${SYSTEM_PROFILE} ssm cancel-command --command-id ${COMMAND_ID}  

接続確認

クライアント側から接続のためのスクリプトを実行して,SSO の認証が通れば IAM の権限で Session Manager や RunCommand の権限が許可されていてかつネットワーク周りの経路が確保されていた状態であれば,Aurora への接続が成功しました.

まとめ

検証で DB クライアントからの接続が成功したので,開発メンバーにも展開しました.これで SSH 鍵の管理がなくなり,踏み台サーバーのセキュリティグループの管理からも開放されます.加えて SSO や IAM で許可した開発者だけが DB につなげるためセキュリティ向上にも資するような仕組みしていけるなと感じました.

参考にさせていただいた記事

dev.classmethod.jp

dev.classmethod.jp

medium.com