さとうです。
プライベートなEC2(外部からのインバウンド通信の接続を許可しない構成)へ外部から接続したい場合にはSSM Session ManagerやEC2 Instance Connectを利用することが多いと思います。
シェルに接続するだけならこれらのサービスを使用してマネジメントコンソールから接続すればいいのですが、これだと外部から直接SCPやSFTPでファイルをプッシュ型で転送したいようなケースには対応することができません。
パブリックサブネットに踏み台サーバを置くことも選択肢になると思いますが、運用負荷やセキュリティ要件など様々な理由でこの踏み台サーバの設置もできない(したくない)ことがあります。
そこでSCP/SFTPを使用してEC2にファイルを転送する経路をどのように確保すればいいのかを整理しました。
つまり、外部からEC2との間にSSHトンネルを確立する方法の整理です。
比較表
表にまとめました。各パターンごとに接続経路のイメージを整理していきます。
ちなみにあくまでEC2との間にSSHトンネルを確立する方法なので、VPCエンドポイントを持ったS3を経由してファイルを移送するなどの手段は対象外です。
No. | サービス | SCPクライアント | IAMユーザー | エージェントのインストール | SCPクライアントへのAWS CLIのインストール | AWSからインターネットへのアウトバウンド通信経路の確保 |
---|---|---|---|---|---|---|
1 | Session Manager | ローカル | 必要(アクセスキー) | 要 | 要(Session Manager Pluginを含む) | 要 |
2 | EC2 Instance Connect | ローカル | 必要(アクセスキー) | 要 | 要 | 不要 |
3 | Network Load Balancer(NLB) | ローカル | 不要 | 不要 | 不要 | 不要 |
※当初CloudShellのVPC Enviromentでもできるのでは?と思っていたのですが、ファイルのアップロードができないという制約があったので除外しました。
各接続パターンのイメージ図
各パターンごとに検証を実施しており、検証条件は以下の通りです。
手順の記載は最小限としておりますのでご了承ください。
- EC2のOSはAmazon Linux 2023(SSM Agentが標準でインストールされている)
- ローカル端末の実行環境はUbuntu24.04
- ファイル転送の検証に使用したファイルの容量は1MB
- ファイル転送の検証は
scp
コマンドで実施- WinSCPなどのProxyCommandをサポートしたツールであればどのツールでも問題なし
Session Managerを使ってローカル端末から転送
接続イメージ図
主なメリット
- インバウンドのポート許可が不要
接続手順(概要)
- 接続したいEC2へSSM Agentをインストールする(されていない場合)
- 接続したいEC2にSSMのアクセス許可を設定する
- ローカル端末にAWS CLIとSession Manager Pluginをインストールする
aws ssm start-session
を使用してローカル端末とEC2の間にSSH接続を確立する
接続例
~/.ssh/config
にProxyCommandを設定する(デフォルトプロファイルを指定する場合、 --profile
は不要)
# SSH over Session Manager Host i-* mi-* ProxyCommand sh -c "aws ssm start-session --profile <プロファイル名> --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'" User ec2-user
scp -i <キーペアのパス> <転送したいローカルファイルのパス> ec2-user@<インスタンスID>:<転送先のパス>
注意点
- Session Managerの仕様上、接続したいEC2は以下いずれかの方法でSession Managerと疎通可能な状態にしておく必要がある
- Protected Subnet(インターネットへの接続経路あり)にある:Nat Gatewayなどを経由してインターネット経由で接続(図はこちら)
- Private Subnet(インターネットへの接続経路なし)にある:VPCエンドポイントを経由して接続(以下参照)
EC2 Instance Connect Endpointを使ってローカル端末から転送
接続イメージ図
主なメリット
- SSM Agentのインストールが不要
- 利用料金が無料
接続手順(概要)
- 接続したいEC2へEC2 Instance Connectをインストールする(Amazon LinuxなどプリインストールされているAMIもあり)
- EC2 Instance Connect Endpointを接続したいEC2と疎通できるサブネットに作成する
各リソースに割り当てたセキュリティグループで以下の通信を許可する
・EC2 Instance Connect Endpoint:アウトバウンドルールでEC2のセキュリティグループへのSSH(22)を許可
・EC2:インバウンドルールでEC2 Instance Connect EndpointのセキュリティグループからのSSH(22)を許可
- ローカル端末にAWS CLIをインストールする
aws ec2-instance-connect open-tunnel
を使用してローカル端末とEC2の間にSSH接続を確立する
接続例
~/.ssh/config
にProxyCommandを設定する(デフォルトプロファイルを指定する場合、 --profile
は不要)
# SSH over EC2 Instance Connect Endpoint Host i-* mi-* ProxyCommand sh -c "aws ec2-instance-connect open-tunnel --profile <プロファイル名> --instance-id %h" User ec2-user
scp -i <キーペアのパス> <転送したいローカルファイルのパス> ec2-user@<インスタンスID>:<転送先のパス>
注意点
- アカウントごとに作成できるエンドポイントは5つまで
- VPCごとに作成できるエンドポイントは1つのみ(=1つのサブネットのみ)
NLBを使ってローカル端末から転送
接続イメージ図
主なメリット
- AWS側の認証認可が不要
- ローカル端末にAWS CLIやSession Manager Pluginなどの追加コンポーネントにインストールが不要
接続手順(概要)
- NLBを作成し、接続したいEC2の22ポートへ転送するターゲットグループを関連付ける
- NLBのセキュリティグループで送信元グローバルIPアドレスの制御を行う(必須ではないが、推奨)
- 接続したいEC2のインバウンドルールでNLBに関連づけたセキュリティグループからのSSH(22)を許可
- ローカル端末からNLBのDNS名を指定してSSH接続を確立する
接続例
AWS固有の手順はなし。普通のリモートサーバにSCPする場合と同じ
scp -i <キーペアのパス> <転送したいローカルファイルのパス> ec2-user@<NLBのDNS名>:<転送先のパス>
注意点
- NLB経由でパブリック向けにポートが公開されてしまうので、セキュリティグループで送信元の制御を行う必要がある
- ロードバランサーなので当然ながらホストの識別ができないため、恒久的に運用する構成としては現実的ではない。一時的な接続経路の確保などを想定したパターン(リスナーを最大50個まで作ることができるので、待ち受けポートで識別することは可能)
ランニングコストの比較
参考までに、各手段のコストの考え方も整理します。 データ転送料金やNLBのLCUなどの従量課金は考慮していません。
SSM Session Manager
Session Manager自体の利用料金は無料ですが、EC2とSession Managerの間に通信経路を確立する必要があるので Session Manager専用にその経路を用意する必要がある場合は、その分の余剰コストが発生します。AZレベルで冗長化する場合はコストが2倍になります。
NAT Gatewayの料金やVPC Endpointの料金などが時間単位で発生します。
VPC Endpointを作成する場合、Session Managerを利用するには以下2つのインターフェース型エンドポイントが必要です。
- com.amazonaws.[region].ssm
- com.amazonaws.[region].ssmmessages
インターネットにアクセスせずにプライベート EC2 インスタンスを管理する | AWS re:Post
EC2 Instance Connect
EC2 Instance Connect EndpointというVPCエンドポイントを作成しますが、これに対する利用料金はかかりません。
EC2 Instance Connect エンドポイント を使用したインスタンスへの接続 - Amazon Elastic Compute Cloud
EC2 Instance Connect エンドポイントの使用に追加コストはかかりません。EC2 Instance Connect エンドポイント を使用して、別のアベイラビリティーゾーンにあるインスタンスに接続する場合、アベイラビリティーゾーン間のデータ転送に追加料金がかかります。
NLB
NLBの利用料金が時間単位で発生します。
ランニングコストの簡易シミュレーション
各パターンで30日(720H)東京リージョンで運用した場合のランニングコストの目安です(時間単位の課金のみ)。
No. | パターン | USD | 単価 |
---|---|---|---|
1 | Session Manager(NAT Gateway) | 44.64 | USD 0.062/H |
2 | Session Manager(VPC Endpoint) | 20.16 | (USD 0.014/H) * 2 |
3 | EC2 Instance Connect | 0 | 無料 |
4 | NLB | 17.496 | USD 0.0243/H |
まとめ
あったらいいなと思ったのでまとめました。
基本的にはSSM Session ManagerかEC2 Instance Connect Endpointを使いたいケースが多くなると思いますが、クライアントにAWS CLIをインストールできなかったり接続先にどうしてもエージェントを入れたくないなどの制約がある場合はNLBを採用する機会があるのかもしれません。
RHELなどのエージェントがプリインストールされていないAMIかつインターネットへの経路がないEC2の場合、カスタムAMIの作成など考慮ポイントが多くなりそうです。
佐藤 航太郎(執筆記事の一覧)
エンタープライズクラウド部 クラウドモダナイズ課
2025年1月入社で何でも試したがりの雑食系です。