目的・やりたいこと

みなさんはEC2上のファイルを、手元のローカル物理PC(Macなど、以下PC)にコピーしたいと思ったことはないでしょうか?
それには色々な方法があるようで、EC2のOSの種類、パブリック/プライベートによって決まってきます。

 

パブリックサブネットの場合

EC2にパブリックIPが付いてるならこれはもう楽です。WindowsならRDPでログインしてコピペで取ってこれますし、LinuxならSCPが使えます。

scp -i [秘密鍵のパス] [ユーザー名]@[パブリックIP]:[EC2のダウンロード元のパス] [ローカルのダウンロード先のパス]

プライベートサブネットの場合

EC2にプライベートIPしかない場合、一般的にはこちらのケースの方が圧倒的に多いと思いますが、少し厄介です。

1.S3に一時的にコピーしてからPCにダウンロード
LinuxならSSMでログインし、S3にアップロードするという手が使えます。
例えば、以下はカレントディレクトリにあるaaaファイルをnozaki-uploadバケットにアップロードするコマンドです。

$ aws s3 cp ./aaa s3://nozaki-upload/
upload failed: ./aaa to s3://nozaki-upload/aaa Unable to locate credentials

ところが、aws configureコマンドなどでEC2にクレデンシャル情報を登録していない場合、「Unable to locate credentials」(認証情報が見つかりません)というエラーが出てきてしまいます。
このため、

  • 新しいEC2でファイルをコピーする度に認証情報を設定するのはセキュリティ上抵抗がある

という問題が生じます。

2.EICエンドポイントを使ってログイン

[技術検証]EC2 Instance Connect エンドポイントの検証 | iret.media

プライベートサブネットのEC2にログインする方法として、EIC(EC2 Instance Connect)エンドポイントが比較的最近できました。これであればLinuxでもWindowsでもログインできます。
ただし、

  • EICエンドポイント(VPCエンドポイント)を作成する必要がある
  • コマンドが煩雑になりがち
    例)
$ scp -i nozaki-key.pem -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id i-0123456789abcdef' ./aaa.txt ec2-user@i-0123456789abcdef:/home/ec2-user/

という問題があります。
そこで、本ブログではSession Manager(SSM)のポートフォワーディング機能を使った比較的簡単な方法をご紹介します。

対象者

プライベートサブネット上のEC2(Linux)上のファイルを、手元のローカル物理PCにコピーしたいユーザー

対象となる技術

  • AWS Systems Manager Session Manager
  • ポートフォワーディング

条件(導入にあたっての前提事項)

  • EC2にSession Managerアクセスを許可するインスタンスプロファイルが割り当てられていること
  • PCとEC2インスタンス間でファイルを端末転送するためには、AWS CLIにてSession Managerのポートフォワーディング機能を使用できるようにする必要があります。このため、PCにあらかじめAWS CLIをインストールしておく必要があります。

概要図

作業の流れ

事前作業

PCにSessionManagerPluginをインストール

% curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3822k  100 3822k    0     0  1274k      0  0:00:02  0:00:02 --:--:-- 1274k

% unzip sessionmanager-bundle.zip
Archive:  sessionmanager-bundle.zip
   creating: sessionmanager-bundle/
  inflating: sessionmanager-bundle/seelog.xml.template  
  inflating: sessionmanager-bundle/THIRD-PARTY  
  inflating: sessionmanager-bundle/LICENSE  
  inflating: sessionmanager-bundle/RELEASENOTES.md  
  inflating: sessionmanager-bundle/NOTICE  
  inflating: sessionmanager-bundle/install  
   creating: sessionmanager-bundle/bin/
  inflating: sessionmanager-bundle/bin/session-manager-plugin  
  inflating: sessionmanager-bundle/README.md  
 extracting: sessionmanager-bundle/VERSION  
 
% sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
Password:
Creating install directories: /usr/local/sessionmanagerplugin/bin
Creating Symlink from /usr/local/sessionmanagerplugin/bin/session-manager-plugin to /usr/local/bin/session-manager-plugin
Installation successful!

手順

以下の作業も全てPC上で行います。

1.EC2に対してSSMでポートフォワード設定を行う
PCで以下のコマンドを実行し、SSM経由でPCのローカルポート10022/TCPを対象EC2の22/TCPに転送するトンネルを確立させます。

% aws ssm start-session --target i-0123456789abcdef --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["22"], "localPortNumber":["10022"]}' --no-verify
urllib3/connectionpool.py:1063: InsecureRequestWarning: Unverified HTTPS request is being made to host 'ssm.ap-northeast-1.amazonaws.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings

Starting session with SessionId: nozaki-67tbgy****
Port 10022 opened for sessionId nozaki-67tbgy****.
Waiting for connections...

コマンド実行後はSSHクライアントの接続待ち状態となるので転送完了まで端末はそのままとします。

2.EC2から欲しいファイルをPCに転送する
PCのSCP/SFTPクライアントソフトウェアにてポートフォワード設定したローカルポートに対して接続を行います。
例)scpコマンドの場合

# scp -i nozaki.pem -o IdentitiesOnly=yes -P 10022 ec2-user@127.0.0.1:/home/ec2-user/aaa ./
The authenticity of host '[127.0.0.1]:10022 ([127.0.0.1]:10022)' can't be established.
ED25519 key fingerprint is SHA256:FLCAyAFO4xbkHlNmb****
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[127.0.0.1]:10022' (ED25519) to the list of known hosts.
aaa                                            100% 3517    25.3KB/s   00:00

転送完了後、AWS-StartPortForwardingSession SSMドキュメントを指定してポートフォワード設定を行ったSSMコマンドは、Ctrl+Cキーで終了しておきます。

 

注意事項

このコマンドを何度も使っていると、以下のような警告が出ることがあります。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:8lt1GC1cCa05lbTHezMDLTMMwz9kxbhDnlznZPBE3Sk.
Please contact your system administrator.
Add correct host key in /var/root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /var/root/.ssh/known_hosts:2
Host key for [127.0.0.1]:10022 has changed and you have requested strict checking.
Host key verification failed.
scp: Connection closed

その際は /var/root/.ssh/known_hosts を開き、「[127.0.0.1]:10022」で始まる行を一旦全て削除してください。
その後再接続し、

Warning: Permanently added '[127.0.0.1]:10022' (ED25519) to the list of known hosts.

と出ればOKです。

 

まとめ

EC2のOSの種類、サブネットがパブリック/プライベートによってファイルコピー手段が次のように変わってきます。

サブネット\EC2のOS Windows Linux
パブリック RDPしてからコピペ SCPコマンド
プライベート EICエンドポイント経由 SSMポートフォワーディング

所要時間

5分

ユースケース

プライベートサブネット上のEC2(Linux)上のファイルを、手元のPCにコピーしたい場合