🔌

ローカルからAWSのVPCネットワーク接続方法いろいろ

2023/08/01に公開

概要

AWSのVPCネットワーク上にサービスを構築した場合に、デバッグなどでローカルからプライベートサブネットにあるECSサービスのタスクやRDSなどのサービスに接続したいことがあると思います。今回はIAMユーザーのアクセスキーを使った接続方法をいくつか紹介します。

※アクセスキーには有効期限がないため、最近のベストプラクティスでは推奨されていないようです。 代替案として、AWS IAM Identity Centerを使った接続方法が推奨されています。詳細は以下を参照してください。
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html

今回紹介する接続

  • 踏み台への接続(多段SSH)
  • ECSサービスタスクへの接続(ExecuteCommand)
  • RDS(MySQL)への接続(多段SSH) ※GUIクライアント
  • RDS(MySQL)への接続(トンネリング) ※GUIクライアント

ポイント

ポイントは以下になります

  • IAMユーザーのアクセスキーを使用する
  • ECSはexecute-commandを使う
  • RDSはGUIクライアントから踏み台を経由して接続する
  • 踏み台はプライベートサブネット上に構築する
  • 踏み台への接続はSSHクライアントを使用する
  • 踏み台のsshポートの穴あけは不要(セッションマネージャーを使うため)
  • 踏み台のキーペアの管理は不要(EC2 Instance Connectを使うため)

前提

  1. IAMユーザーの作成、アクセスキーの発行をしている
  2. AWS CLI バージョン2がインストールされている
  3. aws configureを実施してプロファイルを作成している
  4. セッションマネージャープラグインがインストールされている
  5. SSHクライアントがインストールされている
  6. 踏み台用のEC2インスタンスがプライベートサブネット上に構築されている
  7. 接続したいサービスが踏み台から接続できるようにセキュリティグループが設定されている

踏み台への接続(多段SSH)

1. 独自SSHキーの作成

EC2インスタンス用のキーペアは発行しないため、接続するユーザーが個々に自分でキーを用意します。接続する直前に毎回公開鍵を送信するので、紛失しても作り直せば問題ないですし、EC2キーペアをチームで共有しなくてよいので、管理が不要になるメリットがあります。

$ cd ~/.ssh/
$ ssh-keygen -t rsa -f my_key

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-connect-methods.html

2. ~/.ssh/configbastion という名前のホストを追加する

~/.ssh/config
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は以下の複数のコマンドをワンラインで繋げています。

  1. PATHを通す
  2. aws ec2-instance-connect send-ssh-public-key
  3. aws ssm start-session (ドキュメント名 AWS-StartSSHSession)
    ※AWSコマンドを実行するための許可ポリシーが必要です。

3. sshコマンドで接続する

$ ssh bastion

ECSサービスタスクへの接続(ExecuteCommand)

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html

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 <プロファイル名>

以下の複数のコマンドをワンラインで繋げています。

  1. ECSサービスの最初のタスクIDを変数task_idに格納(ARNの一部にタスクIDが含まれるので、取得したARNをパイプでcutしてタスクIDだけに切り取る)
  2. 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