ローカルからAWSのVPCネットワーク接続方法いろいろ
概要
AWSのVPCネットワーク上にサービスを構築した場合に、デバッグなどでローカルからプライベートサブネットにあるECSサービスのタスクやRDSなどのサービスに接続したいことがあると思います。今回はIAMユーザーのアクセスキーを使った接続方法をいくつか紹介します。
※アクセスキーには有効期限がないため、最近のベストプラクティスでは推奨されていないようです。 代替案として、AWS IAM Identity Centerを使った接続方法が推奨されています。詳細は以下を参照してください。
今回紹介する接続
- 踏み台への接続(多段SSH)
- ECSサービスタスクへの接続(ExecuteCommand)
- RDS(MySQL)への接続(多段SSH) ※GUIクライアント
- RDS(MySQL)への接続(トンネリング) ※GUIクライアント
ポイント
ポイントは以下になります
- IAMユーザーのアクセスキーを使用する
- ECSはexecute-commandを使う
- RDSはGUIクライアントから踏み台を経由して接続する
- 踏み台はプライベートサブネット上に構築する
- 踏み台への接続はSSHクライアントを使用する
- 踏み台のsshポートの穴あけは不要(セッションマネージャーを使うため)
- 踏み台のキーペアの管理は不要(EC2 Instance Connectを使うため)
前提
- IAMユーザーの作成、アクセスキーの発行をしている
- AWS CLI バージョン2がインストールされている
- aws configureを実施してプロファイルを作成している
- セッションマネージャープラグインがインストールされている
- SSHクライアントがインストールされている
- 踏み台用のEC2インスタンスがプライベートサブネット上に構築されている
- 接続したいサービスが踏み台から接続できるようにセキュリティグループが設定されている
踏み台への接続(多段SSH)
1. 独自SSHキーの作成
EC2インスタンス用のキーペアは発行しないため、接続するユーザーが個々に自分でキーを用意します。接続する直前に毎回公開鍵を送信するので、紛失しても作り直せば問題ないですし、EC2キーペアをチームで共有しなくてよいので、管理が不要になるメリットがあります。
$ cd ~/.ssh/
$ ssh-keygen -t rsa -f my_key
~/.ssh/config
に bastion
という名前のホストを追加する
2. Host bastion
User ec2-user
HostName <踏み台EC2インスタンスのインスタンスID>
Port 22
ProxyCommand sh -c "export PATH=/usr/bin:/usr/local/bin && /usr/local/bin/aws ec2-instance-connect send-ssh-public-key --instance-id %h --availability-zone <踏み台があるアベイラビリティゾーン名> --instance-os-user ec2-user --ssh-public-key file://~/.ssh/my_key.pub --profile <プロファイル名> --region <リージョン名> && /usr/local/bin/aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p' --profile <プロファイル名> --region <リージョン名>"
IdentityFile "~/.ssh/my_key"
ProxyCommandは以下の複数のコマンドをワンラインで繋げています。
- PATHを通す
aws ec2-instance-connect send-ssh-public-key
-
aws ssm start-session
(ドキュメント名AWS-StartSSHSession
)
※AWSコマンドを実行するための許可ポリシーが必要です。
3. sshコマンドで接続する
$ ssh bastion
ECSサービスタスクへの接続(ExecuteCommand)
1. ECSタスクロールに以下のポリシーを追加
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
2. タスク定義にゾンビSSMAgentの子プロセスを削除してくれる設定を追加
{
・・・
"containerDefinitions": [
{
・・・
"linuxParameters": {
"initProcessEnabled": true
}
}
]
}
3. ECSサービスの--enable-execute-commandフラグをオン
aws ecs create-service \
--cluster cluster-name \
--task-definition task-definition-name \
--enable-execute-command \
--service-name service-name \
--desired-count 1
4. 以下のコマンドで接続
$ task_id=$(aws ecs list-tasks --cluster <ECSクラスター名> --service <ECSサービス名> --query 'taskArns[0]' --output text --profile <プロファイル名> | cut -f 3 -d '/'); aws ecs execute-command --cluster <ECSクラスター名> --task "$task_id" --container <コンテナ名> --interactive --command "/bin/sh" --profile <プロファイル名>
以下の複数のコマンドをワンラインで繋げています。
- ECSサービスの最初のタスクIDを変数task_idに格納(ARNの一部にタスクIDが含まれるので、取得したARNをパイプでcutしてタスクIDだけに切り取る)
aws ecs execute-command
※ aws ecs list-tasks
や、 aws ecs execute-command
実行するための許可ポリシーが必要です。
RDS(MySQL)への接続(多段SSH) ※GUIクライアント
~/.ssh/configを読み込むことができるGUIクライアントならssh設定でホスト bastion
の情報を入力するだけで、接続できるのですが、以下の理由で現状 TablePlus
でしか使えない接続方法となっています。
DBeaver・・・~/.ssh/configが使えない。
Sequel Pro・・・~/.ssh/configは使えるが、mysql8.0に未対応。
Sequel Ace・・・~/.ssh/configは使えるが内部のバグでawsコマンドが通らないため、ssm接続ができない。参考:https://github.com/Sequel-Ace/Sequel-Ace/issues/1450
MySQL Workbench・・・未調査。
TablePlusでは以下のようにSSH設定を入力すれば接続できます。
RDS(MySQL)への接続(トンネリング) ※GUIクライアント
MySQLクライアントはSequel Aceが使いやすいので、多段SSHではなくトンネルを掘ってポートフォワーディングで接続する方法もあります。
1. トンネルを掘る
$ aws ssm start-session --target <踏み台EC2インスタンスのインスタンスID> --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"portNumber":["3306"],"localPortNumber":["1053"],"host":["<RDSクラスターエンドポイント>"]}' --profile <プロファイル名>
2. GUIクライアントで接続する
トンネルが開いている間は、入り口側(ローカル側)のポートとホストをGUIクライアントに設定することで接続できます。以下は設定例です。ssh設定は不要です。
まとめ
ローカルからIAMユーザーのアクセスキーを使って、踏み台EC2インスタンス、ECSサービスのタスク、RDSクラスターへの接続方法の紹介でした。
Discussion