AWS Systems Manager のセッションマネージャーを使用したリモートホストへのポートフォワード

記事タイトルとURLをコピーする

コーヒーが好きな木谷映見です。

2022年5月27日、AWS Systems Manager(以降、SSM と表記)のセッションマネージャーでリモートホストへのポートフォワード機能をサポートしたアップデートがありました。試してみましょう!!

aws.amazon.com

ポートフォワードとは?

ポートフォワードとは、インターネットから特定のポート番号宛てに届いたパケットを、あらかじめ設定しておいたLAN側の機器に転送する機能です。
以下はリモート先のホスト(web サーバ)へのポートフォワードのイメージですが、ポート毎に複数のサーバーへ振り分けを行ったり、ポート変換を行うことができます。

ドキュメント

セッションマネージャーの概要ページはこちらです。
docs.aws.amazon.com

セッションマネージャーを使用したリモートホストへのポートフォワードについてはこちらです。英語にすると、最新情報が参照できます。
「Start a session」ページに「Starting a session (port forwarding to remote host)」という項目が追加されています。 docs.aws.amazon.com

これまでもセッションマネージャーを使用したポートフォワード機能は提供されていましたが、今回のアップデートではリモートホストへのポートフォワードが可能になりました。

セッションマネージャーでリモートホストへのポートフォワードができると何が嬉しいのか

  • セッションマネージャーでの接続ですので、踏み台サーバそのものをプライベートサブネットに配置することができ、SSH ポートをインターネットにさらさない構成が可能になります。
    ※踏み台サーバは SSM で管理できる必要があるため、NAT Gateway や VPC エンドポイントは必要になります。

  • ドキュメントに記載されているのコマンドがまさに、という感じなのですが、手元の端末からリモートホストへのポートフォワードで RDS にすぐ接続できるようになります。セッションマネージャーを使うには SSM エージェントの導入が必要なのですが、RDS の DB インスタンスはログインできず SSM エージェントの導入もできないので、ここで効果を発揮しそうです。

aws ssm start-session \
    --target instance-id \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters '{"host":["mydb.example.us-east-2.rds.amazonaws.com"],"portNumber":["3306"], "localPortNumber":["3306"]}'
  • 手元のローカル端末からファイルをコピーしたり、コマンドを実行したい場合に使えそうです。特に Windows Server にリモートデスクトップ接続でファイルコピーができるところは便利と感じました。

補足

  • リモート先のホストは、SSM によって管理されなくても OK です。

    • リモート先のホストは SSM Agent 不要
    • リモート先のホストは SSM 用の IAM ロール付与不要
  • 踏み台サーバは SSM で管理できる必要があります。

    • 踏み台サーバは SSM Agent の導入と SSM 用の IAM ロール付与が必要
    • 踏み台サーバは アウトバウンドのポート 443 を制限しない
    • 踏み台サーバは パブリックサブネットに配置するか、NAT Gateway や VPC エンドポイント等で SSM と通信できる構成が必要
  • セッションマネージャーを使用したリモートホストへのポート転送のアップデートを見ますと、SSM Agent のバージョンは 3.1.1374.0 以上が必要です。

  • 手元のローカル端末に AWS CLI、SSM プラグインがインストールされていることが前提で、ポートフォワードコマンド実行に IAM の権限で "ssm:StartSession" Action の許可が必要です。

セッションマネージャーを使用したリモートホストへのポートフォワードをやってみる

今回は東京リージョンで、以下の構成で検証します。

AWS 側の準備

IAM

  • 手元の端末で AWS CLI を実行するための IAM ユーザを用意する

    • アクセスキー・シークレットアクセスキーを発行しておきます。認証情報の取り扱いにはご注意ください。
    • AWS CLI を実行するユーザーには "ssm:StartSession" Action を許可します。
  • 踏み台とする EC2 インスタンス「bastion」に付与する IAM ロールを用意する

    • IAM ロールには AmazonSSMManagedInstanceCore 権限を付与します。

ネットワーク

  • VPC に パブリックサブネット、プライベートサブネットを用意する
  • パブリックサブネットに NAT Gateway を配置し、プライベートサブネットのルートテーブルでインターネット向けの通信のターゲットを NAT Gateway にする

踏み台とする EC2 インスタンス

今回踏み台とする EC2 インスタンス「bastion」はプライベートサブネットに作成します。
SSM で管理される必要があるのは踏み台とする EC2 インスタンス「bastion」だけですので、作成した IAM ロールは「bastion」にだけ付与します。リモート先ホストに IAM ロールは不要です。
SSM Agent のバージョンは 3.1.1374.0 以上が必要です。

現在 EC2 マネジメントコンソールでインスタンスを作成する際デフォルトで選択されている AMI Amazon Linux 2 Kernel 5.10 AMI 2.0.20220426.0 x86_64 HVM gp2 (ami-02c3627b04781eada) にはデフォルトでバージョン 3.1.1188.0 の SSM Agent がインストールされているため、アップデートが必要です。
Amazon Linux 2 インスタンスに SSM Agent を手動でインストールする を参考に、SSM Agent をアップデートします。(Systems Manager の Run Command でも SSM Agent のアップデートが可能です)
踏み台とする EC2 インスタンス「bastion」はセッションマネージャーでブラウザから接続できますので、セッションマネージャーで「bastion」にログインして、SSM Agent をアップデートしていきます。まず以下のコマンドで SSM Aganet の最新バージョンをインストールします。

sudo yum install -y https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm

SSM Agent が起動しているか確認します。

sudo systemctl status amazon-ssm-agent

Active: active (running) となっていれば、SSM Agent が起動しています。 SSM Agent のバージョンを確認します。

yum info amazon-ssm-agent

2022/5/31時点の最新バージョンがインストールされていれば、 Version : 3.1.1476.0と表示されているはずです。

SSM Agent の最新バージョンは以下のサイトで確認できます。 github.com

リモート先ホストを作成する

今回は踏み台とする EC2 インスタンス「bastion」経由で、手元の Windows 10 からポートフォワードで以下 3 種類のホストに接続してみます。以下 3 種類のリモートホストを作成しましょう。
セキュリティグループは、ソースを bastion のセキュリティグループとして、bastion から接続するポートを許可します。

  • Amazon Linux 2(インバウンド SSH 許可)
  • Windows Server 2019(インバウンド RDP 許可)
  • Amazon RDS(MySQL)(インバウンド 3306 許可)

踏み台と違い SSM で管理されていなくてもいいので、 IAM ロールは付与しなくても大丈夫です。リモートホストへポートフォワードで接続する際はキーペアが必要になるので、Linux と Windows のキーペアは作成しておきます。

自分の手元のローカル端末の準備

自分の手元のローカル端末にAWS CLIをインストールしておく

AWS CLI の最新バージョンをインストールまたは更新します。 - AWS Command Line Interface を参考に、自分の手元のローカル端末にAWS CLIをインストールします。私は手元の Windows 10 端末に WSL2 で Ubuntu を導入しており、Ubuntu 上で AWS CLI を実行しています。
詳細手順は以下のブログをご参照ください。
blog.serverworks.co.jp

AWS CLI のバージョンの確認をしておきます。

$ aws --version
aws-cli/2.7.4 Python/3.9.11 Linux/5.10.16.3-microsoft-standard-WSL2 exe/x86_64.ubuntu.20 prompt/off
$

自分の手元のローカル端末に SSM プラグインをインストールしておく

(オプション) AWS CLI 用の Session Manager プラグインをインストールする - AWS Systems Manager を参考に、自分の手元のローカル端末に SSM プラグインをインストールします。
私は手元の Windows 10 端末にインストールした Ubuntu に SSM プラグインをインストールするので、Ubuntu Server に Session Manager プラグインをインストールするを参考にしています。

自分の手元のローカル端末に IAM のクレデンシャル設定をして AWS CLI を実行できるようにしておく

"ssm:StartSession" Action を許可した IAM ユーザで AWS CLI が実行できるよう、クレデンシャルを設定します。

参考:aws configure を使用したクイック設定

リモートホストへポートフォワードしてみる

Starting a session (port forwarding to remote host) を参考に、自分の手元のローカル端末からリモートホストへのポートフォワード用のコマンドを実行します。

aws ssm start-session \
    --target <踏み台 EC2 インスタンスのインスタンス ID> \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters '{"host":["<リモートホストのプライベートIPアドレス、もしくはエンドポイント>"],"portNumber":["接続ポート番号"], "localPortNumber":["ポートフォワード用ローカルポート番号"]}'

Amazon Linux 2

AWS CLI で、リモートホストへのポートフォワード用のコマンドを実行します。

$ aws ssm start-session \
>     --target i-bastionxxxxxxxxxx \
>     --document-name AWS-StartPortForwardingSessionToRemoteHost \
>     --parameters '{"host":["10.123.20.92"],"portNumber":["22"], "localPortNumber":["10022"]}'

Starting session with SessionId: user-port-forwarding-to-remote-hosts-xxxxxxxxxxxxxxxxx
Port 10022 opened for sessionId user-port-forwarding-to-remote-hosts-xxxxxxxxxxxxxxxxx.
Waiting for connections...

ターミナルはこのまま、別途 TeraTerm を開き SSH 接続します。 IP アドレスは 127.0.0.1、ポートはコマンドで指定したポートフォワード用ローカルポート番号を使用します。

ログインユーザは ec2-user 、設定しておいたキーペアを指定します。

ログインできました。

Windows Server 2019

Windows Server にリモートデスクトップ接続するには Administrator のパスワードが必要なので、キーペアを使って Administrator のパスワードを復号してコピーしておきます。
Windows Server 2019 のインスタンスを選択し「接続」をクリックします。
「RDP クライアント」タブを開き、「パスワードを取得」をクリックします。

キーペアを選択し、「パスワードを復号化」をクリックします。

パスワードが表示されるので、コピーしておきます。

AWS CLI に戻り、リモートホストへのポートフォワード用のコマンドを実行します。

$ aws ssm start-session \
    --target i-bastionxxxxxxxxxx \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters '{"host":["10.123.20.129"],"portNumber":["3389"], "localPortNumber":["13389"]}'

Starting session with SessionId: user-port-forwarding-to-remote-hosts-xxxxxxxxxxxxxxxxx
Port 13389 opened for sessionId user-port-forwarding-to-remote-hosts-xxxxxxxxxxxxxxxxx.
Waiting for connections...

ターミナルはこのまま、リモートデスクトップ接続します。 IP アドレスは 127.0.0.1、ポートはコマンドで指定したポートフォワード用ローカルポート番号を使用します。

ログインユーザは Administrator 、コピーしておいたパスワードを指定します。

証明書の警告は、「はい」をクリックして続行します。

ログインできました。

手元の端末からファイルをコピー&ペーストすることもできます。

Amazon RDS (MySQL)

RDS にもログインしてみます。
mysql コマンドでログインするので、自身の端末には以下 MySQL のサイトで「MySQL Installer for Windows」から Windows 用の MySQL をインストールしておきます。
dev.mysql.com

AWS CLI で、リモートホストへのポートフォワード用のコマンドを実行します。

$ aws ssm start-session \
>     --target i-bastionxxxxxxxxxx \
>     --document-name AWS-StartPortForwardingSessionToRemoteHost \
>     --parameters '{"host":["remote-rds.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com"],"portNumber":["3306"], "localPortNumber":["13306"]}'

Starting session with SessionId: user-port-forwarding-to-remote-hosts-xxxxxxxxxxxxxxxxx
Port 13306 opened for sessionId user-port-forwarding-to-remote-hosts-xxxxxxxxxxxxxxxxx.
Waiting for connections...

コマンドプロンプトを開き、ポートフォワード用ローカルポート番号 13306 ポートに接続します。

>mysql -u admin -p -h localhost -P 13306

パスワードを求められるので、 RDS 作成時に設定したマスターユーザーのパスワードを入力します。

>mysql -u admin -p -h localhost -P 13306
Enter password: ***********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 47
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

ログインできました。

所感

手元のローカル端末から AWS 上のリモートホストへファイルをコピーしたり、コマンドを実行したりする際に使える機能と感じました。特に RDS へのログインや Windows Server へのリモートデスクトップ接続は便利です。

AWS 上のホストに SSM Agent の最新バージョンを導入できるのであればセッションマネージャーでのブラウザ接続が可能ですので、それで事足りる場合はセッションマネージャーのブラウザ接続の方をうまく活用できればと思います。

セッションマネージャーのポートフォワード機能を使用する際は、手元のローカル端末に AWS CLI や SSM プラグインのインストール等の準備が必要ですし、 IAM クレデンシャル情報を手元のローカル端末に配置しなければならないところは注意点です。

システムの要件やセキュリティ要件に合わせて、うまくセッションマネージャーのブラウザ接続とポートフォワード機能を使い分けるようにしたいと思います。

参考

blog.serverworks.co.jp

AWS Systems Manager announces support for port forwarding to remote hosts using Session Manager

AWS Systems Manager Session Manager - AWS Systems Manager

Starting a session (port forwarding to remote host)

MySQL :: Developer Zone

emi kitani(執筆記事の一覧)

AS部LX課。2022/2入社、亀の歩みで頑張っています。コーヒーとサウナが好きです。AWS認定11冠