AWS ssm で EC2 インスタンスに sftp 接続してファイルをアップロードする方法【忘備録2024/11】

# 目的
- 業務で使用する Windows から AWS EC2 にファイルをアップロードしたい


### 全部うまくいかなかった
2024年11月20日現在、下記の記事群を参考に作業したがうまくいかなかった。
- WinSCP を使用してローカルからEC2にファイルをアップロード方法
- AWS 公式リファレンスの方法
- SCPコマンドを使用してファイル転送する方法
- セッションマネージャーを利用したSFTP接続
- S3からEC2にファイルを転送する方法
- WinSCPでEC2に接続する方法
- Windows からプライベートサブネットの EC2 に WinSCP でファイルコピーする方法
- プライベートなEC2にファイルを転送する方法
# 作業手順
3時間かかって、ようやくうまくいった。
作業手順を公開する。
### まとめ：作業コマンド コピペ用
- hogeuser と i-*** は適時変更して保存してください
- 記事の最後まで実行するとこのコマンドで、
EC2にファイルをアップロードができるようになります。

```bash:bash
# ssh 接続用コマンド
aws ssm start-session --target i-*** --profile user_profile_name
# 0. ポートリスニング用コマンド
aws ssm start-session --target i-*** --profile user_profile_name --document-name AWS-StartPortForwardingSession --parameters portNumber=22,localPortNumber=9999
# 1. コマンドプロンプトで目的のディレクトリに移動
cd "C:/Users/hogeuser/Documents/2024_11_20_release"
# 2. SFTP接続用コマンド
sftp -P 9999 -i "C:/Users/hogeuser/.ssh/hogeuser-pro" hogeuser@localhost -vex
# 3-1. 接続するインスタンスごとに秘密鍵を作り、接続するポートも変えること。
# 3-2. 同じポートで接続すると接続エラーになる。
```
### 前提条件
- AWS EC2インスタンスが稼働中
- AWS Systems Manager (SSM) が設定済み
- ローカルPCにAWS CLIがインストール済み
### ターミナルの割り振りと説明
- ターミナル A: ローカル PC と EC2 をバイパスを行う
- ターミナル B: EC2 での操作を行う
- ターミナル C: Windows での操作を行う
### SSHキーペアの作成
```powershell:power shell.exe
# ローカルPCでキーペアを生成
ssh-keygen -t rsa -b 4096 -f "C:\Users\hogeuser\.ssh\hogeuser_AWS-pro"
# 接続するインスタンス名を末尾に付けると分かり易くてよい。 ex: -f "hoge_aws_i-***"
```
```powershell:PowerShell.exe
# 表示した内容を後でコピペして使用する
type C:\Users\hogeuser\.ssh\hogeuser_AWS-pro.pub
```
- *** 作成した秘密鍵からログインユーザ以外のアクセス権を削除すること ***
- 作成した秘密鍵を右クリック > プロパティ > セキュリティタブ > 編集 でログインユーザ以外を削除する
- ログインユーザのアクセス権はフルコントロールにする
### SSMセッションの開始とポートフォワーディング
#### ターミナル A
- ターミナルAはリッスンモードになる。MAMP や Docker のようなイメージ。
- ファイルのアップロード作業はターミナル C で行う
- 複数のインスタンスで同時に作業する場合、接続するインスタンスごとにポートを開くこと。
```powershell:power shell.exe
# SSMでポートフォワーディングを設定
aws ssm start-session --target i-*************** --profile aws_pro --document-name AWS-StartPortForwardingSession --parameters portNumber=22,localPortNumber=9999
```
接続の解除は　Ctrl＋C
### EC2インスタンスでの設定
#### ターミナル B
```bash:Bash
# rootユーザーに切り替え
sudo su

# ディレクトリとパーミッションの設定
cd /home/hogeuser
mkdir -p .ssh
chmod 700 .ssh
touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
chown -R hogeuser:hogeuser .ssh
# ここまで必須
#######################################################
# SSHの設定（しなくてもよい）
mv /etc/ssh/sshd_config.d/aws_instance_connect.conf /etc/ssh/sshd_config.d/aws_instance_connect.conf.bak
# カスタム設定の追加（しなくてもよい）
tee /etc/ssh/sshd_config.d/custom.conf << 'EOL'
PubkeyAuthentication yes
PasswordAuthentication no
StrictModes yes
AuthorizedKeysFile .ssh/authorized_keys
EOL
# SSHデーモンの再起動（しなくてもよい）
systemctl restart sshd
```
### 公開鍵の設定
```bash:Bash
# EC2インスタンスで公開鍵を設定
echo "【公開鍵の内容】" > /home/hogeuser/.ssh/authorized_keys
chown hogeuser:hogeuser /home/hogeuser/.ssh/authorized_keys
chmod 600 /home/hogeuser/.ssh/authorized_keys
```
【公開鍵の内容】＝ さっきコピーした内容を張り付ける
### 接続テスト
#### ターミナル C
```powershell:power shell.exe
# デバッグモードでSSH接続テスト
ssh -v -p 9999 -i "C:\Users\hogeuser\.ssh\hogeuser_AWS-pro" hogeuser@localhost
# SFTP接続
sftp -P 9999 -i "C:\Users\hogeuser\.ssh\hogeuser_AWS-pro" hogeuser@localhost
```
### ファイル転送方法
#### SFTPコマンド
```bash:Bash
put "C:/Users/hogeuser/Documents/ファイル名" # フルパスでファイルをアップロード
put "C:/Users/hogeuser/Documents//*.txt" # 複数のファイルをアップロード
put uptest.txt release_2024_11_20/ # 第二引数はアップロードするディレクトリ名
exit # 終了
```
- ディレクトリの所有者とパーミッションを設定を忘れずに
sudo chown hogeuser:hogeuser release_2024_11_20/
sudo chmod 755 release_2024_11_20/
#### SCPコマンド
```bash:Bash
# 単一ファイル転送
scp -P 9999 -i "C:\Users\hogeuser\.ssh\hogeuser_AWS-pro" "ローカルファイルパス" hogeuser@localhost:~/
# ディレクトリ転送
scp -P 9999 -i "C:\Users\hogeuser\.ssh\hogeuser_AWS-pro" -r "ローカルディレクトリパス" hogeuser@localhost:~/
# 終了
quit or bye
```
#### Windowsコマンド
```powershell:PowerShell.exe
!dir # Windowsでのディレクトリ内容表示
!echo %CD% # 現在のディレクトリを確認
lpwd # ローカル環境の現在の作業フォルダーの表示
lcd # ローカル環境の作業フォルダの移動
```
sftp コマンド中は Tab による変換ができない。
Windowsのエクスプローラーから移動したいフォルダのパスをコピーすると便利
#### WindowsSFTP 動かないコマンド
```powershell:PowerShell.exe
!pushed "C:Users/hogeuser" # not work
!cd # not work
```
### トラブルシューティング
- パーミッションエラーの場合は、ディレクトリとファイルの所有権と権限を確認
- 認証エラーの場合は、公開鍵の内容と authorized_keys の内容を確認
- 接続エラーの場合は、SSMセッションが正常に動作しているか確認
### 注意事項
- セキュリティのため、パスワード認証は無効化しておく
- 秘密鍵は安全に保管し、共有しない
- SSHの設定変更後は必ずSSHデーモンを再起動する

以上。

みんな公式リファレンスの内容でよく問題なく作業できるな。
公式リファレンスで暗黙知になっている部分を読み解けるぐらいに、技術力と経験の基準が高いのだろうか。