EC2 Instance Connect Endpoint経由でWindows ServerにRDP接続してみた

2023.06.15

しばたです。

先日リリースされたEC2 Instance Connect Endpointですが、Windows ServerへRDP接続するにはAWS CLIを使う必要があります。
これまでAWS CLIが新機能に対応していなかっため動作確認できなかったのですが、本日対応バージョンがリリースされたので実際に動作確認してみました。

前提条件

EC2 Instance Connect Endpointを使いRDP接続するためには以下の前提条件を満たす必要があります。

1. VPC Endpointのセキュリティグループ設定

EC2 Instance Connect Endpointを導入する際にVPC Endpointを作成しますが、このVPC Endpointに紐づけるセキュリティグループ設定で「RDPプロトコル(TCP 3389)のアウトバウンド通信を許可」しておく必要があります。

EC2 Instance Connect自体はSSH通信を主としたサービスであるので設定漏れをしやすいところだと思いますのでご注意ください。
なおインバウンド通信は全てブロックして構いません。

2. 所定バージョンのAWS CLIをインストール

Windows ServerへRDP接続する前準備でaws ec2-instance-connect open-tunnelコマンドを使用します。
このコマンドが使えるバージョンのAWS CLIを接続元クライアント環境にインストールしておく必要があります。

本日時点では最新のAWS CLI v2(Ver.2.12.0)のみ対応しており、AWS CLI v1は未対応でした。

# AWS CLI Ver.2.12.0以降が対象
PS C:\> aws --version
aws-cli/2.12.0 Python/3.11.3 Windows/10 exe/AMD64 prompt/off

# aws ec2-instance-connect open-tunnel コマンドが使えること
PS C:\> aws ec2-instance-connect help
# ・・・省略・・・
Available Commands
******************

* help

* open-tunnel

* send-serial-console-ssh-public-key

* send-ssh-public-key

* ssh

試してみた

それでは早速動作確認をしていきます。

検証環境

今回は私の検証用AWSアカウントにVPC環境及びWindows Server 2022 EC2インスタンス、そしてEC2 Instance ConnectのVPC Endpointを用意します。
接続元のクライアント環境(Windows 11 Pro)にはAWS CLI Ver.2.12.0を導入済みです。

ざっくり上図の構成となります。
各リソースの詳細な作成手順は割愛しますが以下の設定を施しています。

  • VPC内のPrivateサブネットはインターネットアクセス不可
  • Windows Server 2022 EC2は本日時点で最新のAMI(ami-0373bd2f6665b3540 : Windows_Server-2022-Japanese-Full-Base-2023.05.10)を使用
    • IAMロールなどの設定は無し
    • セキュリティグループでVPC EndpointからのRDP接続(TCP 3389)を許可
  • VPC EndpointのセキュリティグループでRDP(TCP 3389)のアウトバウンド通信を許可
  • クライアント環境でAWS CLIを利用可能に初期設定済み
    • your_profileという名前のプロファイルを設定済み

1. aws ec2-instance-connect open-tunnelコマンドの実行

最初にクライアント環境でaws ec2-instance-connect open-tunnelコマンドを実行し接続先インスタンスに対するWebSocketトンネルを作成してやります。
このコマンドでは様々なパラメーター指定が可能ですが、最低限以下の様に--instance-id,--remote-port,--local-portパラメーターを設定してやればOKです。

# WebSocketトンネルを張る
aws ec2-instance-connect open-tunnel --instance-id "宛先インスタンスID" --remote-port 3389 --local-port "任意の空きポート"

今回は--local-portに13389を指定してやります。
--remote-portはEC2インスタンス側の接続ポートになるので3389になります。

# コマンド実行例
PS C:\> $env:AWS_PROFILE="your_profile"
PS C:\> aws ec2-instance-connect open-tunnel --instance-id "i-xxxxxxxxxxxx" --remote-port 3389 --local-port 13389

2. RDP接続の実施

問題無くコマンドが実行できれば下図の様に

Listening for connections on port 13389.

のメッセージを表示してWebSocketトンネルが張られます。

この状態でRemote Desktop Clientを起動してlocalhost:13389に接続してやればEC2インスタンスにログインできます。

(Windows Serverは鍵認証できないのでパスワード入力必須)

いい感じですね。

補足. WebSocketトンネルの作成に失敗する場合

例えばセキュリティグループの設定ミスなどによりWebSocketトンネルを張れない場合は以下の様なエラーメッセージが表示されます。

# 失敗時 : この例はセキュリティグループの設定を誤りEC2インスタンスに対してTCP 3389の通信が出来ない場合のエラー
PS C:\> aws ec2-instance-connect open-tunnel --instance-id "i-xxxxxxxxxxxx" --remote-port 3389 --local-port 13389
Listening for connections on port 13389.
[1] Accepted new tcp connection, opening websocket tunnel.
2023-06-15 07:39:22,688 - awscli.customizations.ec2instanceconnect.websocket - ERROR - [1] Encountered error with websocket: (10053, '確立された接続がホスト コンピューターのソウトウェアによって中止されました。', None, 10053, None)
[1] Closing tcp connection.

エラーメッセージの内容に応じてよしなに対処してください。

最後に

以上となります。

動作原理および使用するコマンドは異なりますが、雰囲気としてはSSMポートフォワードを使ってRDP接続する際の手順に近いと考えてもらうと良いでしょう。
こちらはSession Manager Pluginの導入は不要でAWS CLIだけで完結するので少しだけ導入の手間も省けます。

環境に応じて両者を使い分けると良いでしょう。