SSHポートフォワーディングでEC2 Windowsインスタンスに安全にアクセスする
プライベートサブネット内のEC2 WindowsインスタンスにSSH踏み台ホスト経由でアクセスし、RDPを一切パブリックインターネットに晒さない方法。
EC2 Windowsインスタンスをプライベートサブネットに配置し、パブリックサブネット内の踏み台ホスト経由でアクセスすることは、インスタンスを直接インターネットに晒すことなくリモートデスクトップアクセスを保護するための一般的なパターンです。
この方法で保護されるのはクライアントと踏み台ホスト間の接続のみです。踏み台ホストとEC2 Windowsインスタンスの間には暗号化は適用されません。
全体のアーキテクチャは以下の図の通りです。

バックエンドの構築
VPC
対象のVPC内にプライベートサブネットを作成します。適切なサブネットが既に存在する場合、この手順は省略できます。

ルートテーブルを作成し、プライベートサブネットに関連付けます。

このルートテーブルからインターネットゲートウェイが除外されていることを必ず確認してください。含まれていると、そのサブネットが実質的にパブリックサブネットになってしまいます。

EC2 Windowsインスタンスにインターネットアクセスが必要な場合は、パブリックサブネットにNATゲートウェイを作成し、ルートテーブルにアタッチします。
NATゲートウェイの稼働には追加コストがかかります。


SSH踏み台ホスト
- 踏み台ホストとして機能するEC2インスタンスをパブリックサブネットに起動する。
- セキュリティグループを設定し、ポート22(SSH)と3389(RDP)へのインバウンドトラフィックを許可する。
Elastic IP(EIP)を割り当てておくと、踏み台ホストへのアクセスが容易になります。
EC2 Windowsインスタンス
- EC2 Windowsインスタンスをプライベートサブネットに起動する。
- EC2ダッシュボードの
Get Windows Passwordオプションを使ってリモートデスクトップの認証情報を取得する。 - セキュリティグループを制限し、ポート22および3389へのインバウンドトラフィックを踏み台ホストからのみ許可する。

接続のテスト
ローカルのターミナルから以下のコマンドを実行し、EC2 Windowsインスタンスへの安全な接続を確立します。
ssh -i <YOUR_PRIVATE_KEY> -L 13389:<YOUR_EC2_WINDOWS_IP>:3389 ec2-user@<YOUR_SSH_BASTION_IP>このコマンドは、ローカルのポート13389へのトラフィックを、踏み台ホスト経由でプライベートサブネット内のEC2 Windowsインスタンスへ転送します。その後、localhost:13389に接続することでリモートデスクトップセッションを開始できます。


まとめ
EC2 Windowsインスタンスをインターネットゲートウェイへのルートを持たないプライベートサブネットに置き、パブリックサブネット内のSSH踏み台ホスト経由でアクセスするようにしたことで、RDPを一切パブリックインターネットに晒さずに済むようになりました。これを支えているのはプライベートインスタンス側のセキュリティグループです。ポート22と3389へのアクセスを、広めのCIDR範囲ではなく踏み台ホストからのみに制限しています。あとはssh -L 13389:<EC2_WINDOWS_IP>:3389がRDPセッションを踏み台経由でトンネリングしてくれるので、クライアントマシン上のlocalhost:13389から、VPC外部への経路を一切持たないインスタンスにも到達できるようになります。ただしこのトンネルが暗号化するのはクライアントから踏み台までの区間だけなので、最も入念に固めるべきは踏み台ホスト自体です。開放的なCIDR範囲は避け、セキュリティグループを絞り込んだうえで、できればEIPを既知の管理アクセス用に確保しておくとよいでしょう。
Related posts
Session Manager で EC2 に接続する(SSH 不要)
Systems Manager の Session Manager を使い、SSH キーも踏み台サーバーもポート 22 の開放も不要な状態で EC2 インスタンスにシェルアクセスする方法。
PhpStormとXdebugでAWS EC2上のPHPをリモートデバッグする
PhpStormとXdebugを使ってEC2上のPHPアプリケーションをリモートデバッグする方法。サーバー側のini設定からIDEのパスマッピングまでを解説。
EC2上でProxy.pyを軽量HTTPプロキシとして動かす
Proxy.pyにはそれ自体の認証機構がないため、EC2インスタンス上で動かしつつSSHトンネル経由で安全にアクセスする方法です。
Cognito User PoolsとOIDCでSlackサインインを実装する
Cognito user poolをOIDC経由でSlackと連携させ、"Sign in with Slack"をAmplifyでNext.jsアプリに組み込みます。
Lambda Web AdapterでFastAPIをAWS Lambdaにデプロイする
Lambda Web Adapterを使うと、FastAPIで書いたAPIバックエンドをコンテナのまま単一のLambda関数にデプロイできます。
