EC2 Instance Connect エンドポイントを使って手元の Windows 11 端末からプライベートサブネットの EC2 にSSH 接続し、SCP コマンドでファイルコピーしてみた

2023.11.07

コーヒーが好きな emi です。

EC2 Instance Connect エンドポイントを使って手元の Windows 11 端末からプライベートサブネットの EC2 にSSH 接続し、SCP コマンドでファイルコピーしてみました。
検証手順を連携します。

構成図

以下のような構成で検証します。

検証

事前準備

VPC は作成しておいてください。
プライベートサブネットが一つあれば OK です。

セキュリティグループの作成

EC2 Instance Connect (EIC) Endpoint 用セキュリティグループと、EC2 インスタンス(Amazon Linux 2)用セキュリティグループの二つを作成します。

EC2 コンソールから、以下のようにセキュリティグループを作成します。

EC2 Instance Connect (EIC) Endpoint 用セキュリティグループ:eic-endpoint-test-endpoint-sg

セキュリティグループ タイプ プロトコル ポート範囲 送信先 説明
インバウンド なし なし なし なし なし
アウトバウンド RDP TCP 22 sg-xxx(EC2 インスタンス(Amazon Linux 2)用セキュリティグループ) to eic-endpoint-test-ec2-linux-sg

EC2 インスタンス(Amazon Linux 2)用セキュリティグループ:eic-endpoint-test-ec2-linux-sg

セキュリティグループ タイプ プロトコル ポート範囲 送信先 説明
インバウンド RDP TCP 22 sg-xxx(EC2 Instance Connect (EIC) Endpoint 用セキュリティグループ) from eic-endpoint-test-endpoint-sg
アウトバウンド すべてのトラフィック すべて すべて 0.0.0.0/0

EC2 Instance Connect (EIC) Endpointの作成

VPC コンソールの Endpoints から「エンドポイントを作成」をクリックし、以下のように VPC エンドポイントを作成します。

項目 設定値 備考
名前タグ - オプション eic-endpoint-test 任意のエンドポイント名
サービスカテゴリ EC2 インスタンス接続エンドポイント
VPC eic-endpoint-test-vpc 作成した VPC を設定
追加設定 - Preserve Client IP(クライアント IP の保持) チェックしない オン(true)の場合、インスタンスのセキュリティグループはクライアント IP アドレスからの受信トラフィックを許可する必要がある
セキュリティグループ eic-endpoint-test-endpoint-sg 作成しておいた EIC Endpoint 用セキュリティグループを設定
Subnet 作成済みのプライベートサブネットを設定
タグ key:Name、value:eic-endpoint-test 任意のタグを設定

EC2 インスタンス(Amazon Linux 2)の作成

EC2 コンソールから、以下のように Amazon Linux 2 を作成します。

項目 設定値 備考
名前 eic-endpoint-test-ec2-linux 任意の EC2 名
AMI ami-0e2e9a769def245c4 Amazon Linux 2 Kernel 5.10 AMI 2.0.20231101.0 x86_64 HVM gp2 2023/11/06 時点で最新の Amazon Linux 2 AMI
インスタンスタイプ t3.micro
キーペア 任意のキーペアを作成して設定 .pem 形式のキーペアを設定してください。
サブネット eic-endpoint-test-subnet-private1-ap-northeast-1a 作成済みの VPC とプライベートサブネットを設定
セキュリティグループ eic-endpoint-test-ec2-linux-sg 作成しておいた EC2 用セキュリティグループを設定

SCP コマンドを使用する際はキーペアが必要になりますので、作成・設定してください。
IAM ロール(IAM インスタンスプロファイル)の設定は不要です。

接続元の端末で AWS CLI とプロファイル(IAM ユーザーのアクセスキー)の設定

接続元とする手元の端末で AWS CLI のインストールとプロファイル(IAM ユーザーのアクセスキー)の設定をします。
今回は以下ブログを参考に、私が使用している Windows 11 で設定します。

コマンドプロンプトで以下のように AWS CLI のバージョンを確認できます。

C:\Users\kitani.emi>aws --version
aws-cli/2.13.30 Python/3.11.6 Windows/10 exe/AMD64 prompt/off

C:\Users\kitani.emi>

AWS CLI 用の IAM ユーザー「eic-endpoint-test」を作成し、アクセスキーを手元の端末に設定します。
EC2 Instance Connect Endpoint を使用するための IAM 権限は以下のドキュメントを参考にしました。

今回私が設定した権限は以下になります。

eic-endpoint-test-policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EC2InstanceConnect",
            "Effect": "Allow",
            "Action": "ec2-instance-connect:OpenTunnel",
            "Resource": [
                "arn:aws:ec2:ap-northeast-1:123456789012:instance-connect-endpoint/eice-03a123cad4174aaf4"
            ],
            "Condition": {
                "NumericEquals": {
                    "ec2-instance-connect:remotePort": "22"
                },
                "IpAddress": {
                    "ec2-instance-connect:privateIpAddress": "10.0.10.11/32"
                }
            }
        },
        {
            "Sid": "Describe",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceConnectEndpoints"
            ],
            "Resource": "*"
        },
        {
            "Sid": "SendSSHPublicKey",
            "Effect": "Allow",
            "Action": "ec2-instance-connect:SendSSHPublicKey",
            "Resource": "arn:aws:ec2:ap-northeast-1:123456789012:instance/*"
        }
    ]
}
  • "ec2-instance-connect:OpenTunnel" を、作成した EIC エンドポイントの arn に対し、ポート 22 で許可します。
  • 10.0.10.11/32 は作成した Amazon Linux 2 のプライベート IP アドレスです。
  • "ec2-instance-connect:SendSSHPublicKey" も許可しました。必要であればこれも対象ポートや対象リソースを指定して制限してください。

この権限を付与した IAM ユーザーのアクセスキーを発行し、.aws 配下の config ファイルと credentials ファイルにプロファイル情報を追記します。

  • config ファイルの例
[default]
region = ap-northeast-1
output = json

[profile eic-endpoint-test]
region = ap-northeast-1

[profile test-role]
region = ap-northeast-1
  • credentials の例
[default]
aws_access_key_id = AKIAxxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

[eic-endpoint-test]
aws_access_key_id = AKIAxxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

[test-role]
aws_access_key_id = AKIAxxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

SSH 接続

それでは SSH 接続してみます。
EC2 Instance Connect Endpoint Service は AWS 側で自動作成されるので、ユーザーは気にしなくてよいです。

ec2-instance-connect ssh コマンドで SSH 接続する方法

ec2-instance-connect ssh コマンドを使って SSH 接続することができます。
Linux インスタンス用ユーザーガイド|EC2 Instance Connect を使用して、AWS CLI で Linux インスタンスに接続します。 も参考にしてください。

コマンドプロンプトで以下のコマンドを実行します。

aws ec2-instance-connect ssh ^
--instance-id i-xxxxxxxxxxxxxxxxx ^
--eice-options maxTunnelDuration=3600,endpointId=eice-xxxxxxxxxxxxxxxxx ^
--os-user ec2-user ^
--profile eic-endpoint-test
  • i-xxxxxxxxxxxxxxxxx:接続する EC2 インスタンスのインスタンス ID
  • eice-xxxxxxxxxxxxxxxxx:作成した EIC エンドポイントのエンドポイント ID
  • --profile:IAM ユーザーのクレデンシャルを手元の端末に設定した際のプロファイル

  • 実行結果例(途中 yes 入力)

    C:\Users\kitani.emi>aws ec2-instance-connect ssh ^
    More? --instance-id i-0a1d205bd3242dca6 ^
    More? --eice-options maxTunnelDuration=3600,endpointId=eice-03a123cad4174aaf4 ^
    More? --os-user ec2-user ^
    More? --profile eic-endpoint-test
    The authenticity of host '10.0.10.11 (<no hostip for proxy command>)' can't be established.
    ECDSA key fingerprint is SHA256:Y7itjFfrB9SLtJwjcph0I6HiY7M/Hzhrdxxxxxxxxxx.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added '10.0.10.11' (ECDSA) to the list of known hosts.
       ,     #_
       ~\_  ####_        Amazon Linux 2
      ~~  \_#####\
      ~~     \###|       AL2 End of Life is 2025-06-30.
      ~~       \#/ ___
       ~~       V~' '->
        ~~~         /    A newer version of Amazon Linux is available!
          ~~._.   _/
             _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
           _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    
    [ec2-user@ip-10-0-10-11 ~]$
    [ec2-user@ip-10-0-10-11 ~]$

コマンドプロンプトで SSH 接続できました。すごいです。
違う方法も試すので、一旦 exit で SSH 接続を切断します。

ec2-instance-connect open-tunnel コマンドでローカルマシンと EC2 インスタンス間に SSH トンネルを開いておいて SSH 接続する方法

ec2-instance-connect open-tunnel コマンドでローカルマシン(今回は手元の Windows 11 端末)と EC2 インスタンス間に SSH トンネルを開いておいて SSH 接続する方法も使えます。
Linux インスタンス用ユーザーガイド|SSH を使用した Linux インスタンスへの接続 も参考にして下さい。

まず、コマンドプロンプトを開き、以下のコマンドで SSH トンネルを開きます。

aws ec2-instance-connect open-tunnel ^
    --instance-id i-xxxxxxxxxxxxxxxxx ^
    --remote-port 22 ^
    --local-port 10022 ^
    --profile eic-endpoint-test
  • 実行結果例
    C:\Users\kitani.emi>aws ec2-instance-connect open-tunnel ^
    More?     --instance-id i-0a1d205bd3242dca6 ^
    More?     --remote-port 22 ^
    More?     --local-port 10022 ^
    More?     --profile eic-endpoint-test
    Listening for connections on port 10022.

最後が Listening for connections on port 10022. となり、SSH トンネルが開いた状態になります。
このコマンドプロンプトのウィンドウは開いたままにしてください。

では、新しく別のウィンドウでコマンドプロンプトを開きます。
新しく開いたコマンドプロンプトで以下のコマンドを入力します。

ssh -i "ローカルマシン(手元の端末)に保存してあるキーペアのパス" ec2-user@localhost -p 10022
  • 実行結果例
    C:\Users\kitani.emi>ssh -i "C:\Users\kitani.emi\key\xxx-tokyo-key.pem" ec2-user@localhost -p 10022
    Last login: Mon Nov  6 09:35:54 2023 from ip-10-0-10-221.ap-northeast-1.compute.internal
       ,     #_
       ~\_  ####_        Amazon Linux 2
      ~~  \_#####\
      ~~     \###|       AL2 End of Life is 2025-06-30.
      ~~       \#/ ___
       ~~       V~' '->
        ~~~         /    A newer version of Amazon Linux is available!
          ~~._.   _/
             _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
           _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    
    [ec2-user@ip-10-0-10-11 ~]$

接続できました。
exit で SSH 接続を切断します。

SSH トンネルを開いた方のウィンドウで Ctr+C を押下し、SSH トンネルも閉じます。

ProxyCommand を使って ec2-instance-connect open-tunnel コマンドと SSH コマンドを組み合わせて SSH 接続する方法(Mac)

お手元の端末が Mac の場合、単一の接続であれば、以下のように ProxyCommand を使って ec2-instance-connect open-tunnel コマンドと SSH コマンドを組み合わせて SSH 接続することもできます。

ssh -i my-key-pair.pem ec2-user@i-xxxxxxxxxxxxxxxxx \
    -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id i-xxxxxxxxxxxxxxxxx'

残念ながらこのコマンドは Windows のコマンドプロンプトでは実行できません。
Windows で ProxyCommand を使用するためには ssh クライアントを含む Git Bash や Cygwin、WSL(Windows Subsystem for Linux)などの環境が必要です。

SCP コマンドでファイルコピー

手元の端末のファイルを SCP コマンドで EC2 にコピー

SCP コマンドでファイルコピーするために、SSH トンネルが開いた状態にしておきます。

コマンドプロンプトを開き、以下のコマンドで SSH トンネルを開きます。

aws ec2-instance-connect open-tunnel ^
    --instance-id i-xxxxxxxxxxxxxxxxx ^
    --remote-port 22 ^
    --local-port 10022 ^
    --profile eic-endpoint-test
  • 実行結果例
    C:\Users\kitani.emi>aws ec2-instance-connect open-tunnel ^
    More?     --instance-id i-0a1d205bd3242dca6 ^
    More?     --remote-port 22 ^
    More?     --local-port 10022 ^
    More?     --profile eic-endpoint-test
    Listening for connections on port 10022.

最後が Listening for connections on port 10022. となり、SSH トンネルが開いた状態になります。
このコマンドプロンプトのウィンドウは開いたままにしてください。

では、新しく別のウィンドウでコマンドプロンプトを開きます。
新しく開いたコマンドプロンプトで以下のコマンドを入力し、手元の端末のファイルを EC2 にコピーします。

scp -P 10022 -i "ローカルマシン(手元の端末)に保存してあるキーペアのパス" "ローカルマシン(手元の端末)のファイルパス" ec2-user@localhost:コピーしたファイルを置きたいリモートマシン(EC2)のファイルパス
  • 実行結果例
    C:\Users\kitani.emi>scp -P 10022 -i "C:\Users\kitani.emi\key\xxx-tokyo-key.pem" "C:\work\test\20231106_test.txt" ec2-user@localhost:~/
    20231106_test.txt                                                                     100%    0     0.0KB/s   00:00
    
    C:\Users\kitani.emi>

SCP コマンドで、手元の端末のファイルを EC2 にコピーできました。
SSH 接続して、ファイルがコピーできたか確認してみます。

以下の SSH 接続コマンドを実行します。

ssh -i "ローカルマシン(手元の端末)に保存してあるキーペアのパス" ec2-user@localhost -p 10022
  • 実行結果例
    C:\Users\kitani.emi>ssh -i "C:\Users\kitani.emi\key\xxx-tokyo-key.pem" ec2-user@localhost -p 10022
    Last login: Mon Nov  6 10:05:13 2023 from ip-10-0-10-221.ap-northeast-1.compute.internal
       ,     #_
       ~\_  ####_        Amazon Linux 2
      ~~  \_#####\
      ~~     \###|       AL2 End of Life is 2025-06-30.
      ~~       \#/ ___
       ~~       V~' '->
        ~~~         /    A newer version of Amazon Linux is available!
          ~~._.   _/
             _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
           _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    
    [ec2-user@ip-10-0-10-11 ~]$

SSH 接続できました。

ls -la コマンドで、コピーしたファイルが存在するか確認します。

[ec2-user@ip-10-0-10-11 ~]$ ls -la
total 20
drwx------ 3 ec2-user ec2-user 136 Nov  6 10:13 .
drwxr-xr-x 3 root     root      22 Nov  6 09:16 ..
-rw-rw-r-- 1 ec2-user ec2-user   0 Nov  6 10:13 20231106_test.txt
-rw------- 1 ec2-user ec2-user 106 Nov  6 10:10 .bash_history
-rw-r--r-- 1 ec2-user ec2-user  18 Jul 15  2020 .bash_logout
-rw-r--r-- 1 ec2-user ec2-user 193 Jul 15  2020 .bash_profile
-rw-r--r-- 1 ec2-user ec2-user 231 Jul 15  2020 .bashrc
drwx------ 2 ec2-user ec2-user  29 Nov  6 09:46 .ssh
-rw------- 1 ec2-user ec2-user 869 Nov  6 09:46 .viminfo
[ec2-user@ip-10-0-10-11 ~]$

コピーしたファイルがホームディレクトリにあるのが分かります。

EC2 上のファイルを手元の端末にコピー

続いて、EC2 上のファイルを手元の端末にコピーしてみます。
SSH 接続した EC2 上でテスト用ファイルを作成します。

touch 20231106_test_EC2_file.txt
  • 実行結果例
    [ec2-user@ip-10-0-10-11 ~]$ touch 20231106_test_EC2_file.txt
    [ec2-user@ip-10-0-10-11 ~]$

ls -la コマンドで、作成したファイルが存在するか確認します。

[ec2-user@ip-10-0-10-11 ~]$ ls -la
total 20
drwx------ 3 ec2-user ec2-user 170 Nov  6 10:18 .
drwxr-xr-x 3 root     root      22 Nov  6 09:16 ..
-rw-rw-r-- 1 ec2-user ec2-user   0 Nov  6 10:18 20231106_test_EC2_file.txt
-rw-rw-r-- 1 ec2-user ec2-user   0 Nov  6 10:13 20231106_test.txt
-rw------- 1 ec2-user ec2-user 106 Nov  6 10:10 .bash_history
-rw-r--r-- 1 ec2-user ec2-user  18 Jul 15  2020 .bash_logout
-rw-r--r-- 1 ec2-user ec2-user 193 Jul 15  2020 .bash_profile
-rw-r--r-- 1 ec2-user ec2-user 231 Jul 15  2020 .bashrc
drwx------ 2 ec2-user ec2-user  29 Nov  6 09:46 .ssh
-rw------- 1 ec2-user ec2-user 869 Nov  6 09:46 .viminfo
[ec2-user@ip-10-0-10-11 ~]$

それでは以下のコマンドを入力し、手元の端末のファイルを EC2 にコピーします。

scp -P local_port -i "ローカルマシン(手元の端末)に保存してあるキーペアのパス" ec2-user@localhost:リモートマシン(EC2)のファイルパス "コピーしたファイルを置きたいローカルマシン(手元の端末)のパス"
  • 実行結果例
    C:\Users\kitani.emi>scp -P 10022 -i "C:\Users\kitani.emi\key\xxx-tokyo-key.pem" ec2-user@localhost:~/20231106_test_EC2_file.txt "C:\work\test"
    20231106_test_EC2_file.txt                                                            100%    0     0.0KB/s   00:00
    
    C:\Users\kitani.emi>

SCP コマンドで、手元の端末のファイルを EC2 にコピーできました。
エクスプローラーで確認すると、EC2 上で作成したファイルがコピーされて存在していることが分かります。

ProxyCommand を使って ec2-instance-connect open-tunnel コマンドと SCP コマンドを組み合わせてファイルコピーする方法(Mac)

お手元の端末が Mac の場合、以下のように ProxyCommand を使って ec2-instance-connect open-tunnel コマンドと SCP コマンドを組み合わせてファイルコピーすることもできます。

scp -i my-key-pair.pem \
 -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id i-xxxxxxxxxxxxxxxxx' \
 ./test.txt ec2-user@i-xxxxxxxxxxxxxxxxx:/home/ec2-user/

残念ながらこのコマンドは Windows のコマンドプロンプトでは実行できません。
Windows で ProxyCommand を使用するためには ssh クライアントを含む Git Bash や Cygwin、WSL(Windows Subsystem for Linux)などの環境が必要です。

参考