AWSのEC2(Amazon Linux 2)にWindows10からIAMユーザーでSSH接続するときにハマったところ

# ハマったところ
結論から言うと、[EC2](https://console.aws.amazon.com/ec2/)コンソールで作った鍵ファイル(~.pemファイル) の権限でアクセスできずハマりました。

また、やってて思ったのは、SSHについて「リモート接続するためのプロトコル」くらいのざっくりしたことしか知らなかったので、初心者の人は何をやるべきかがドキュメントだけでは分からないと思います。

# 環境
ローカル：Windows 10 21H2
~~SSHクライアント：TeraTerm 4.105~~
リモート：Amazon Linux 2

# SSHの流れ
~~まず何をすればSSHということができるか、という流れです。~~

* SSHクライアント(OpenSSH)を使用してローカル側が持っておくための~~鍵ファイル~~秘密鍵を作成する。
* クライアントはそれを使って公開鍵を作る。
* ~~ホスト~~リモート側のLinux でSSH 接続用のユーザーを作る。（必須ではない）
* ~~ホスト~~リモート側のユーザーディレクトリに公開鍵を追加する。(クライアント側で作った公開鍵の文字列をファイルにコピーするだけ)
* あとは TeraTerm などで~~SSH 接続用のユーザーで~~接続。


以下、大まかなやり方です。ネットを探すとこの辺りは出てくるので詳細は割愛します。
## ローカル~~クライアント~~ 側で秘密鍵（pem ~~鍵~~ ファイル）を生成（キーペア）
キーペアは、EC2コンソールで簡単に出来ます。最初にIAMユーザーをAdministratorAccessで作っておいて、EC2コンソールで設定するとそのユーザー用の鍵を作ってくれます。

## 公開鍵 ~~認証キー~~ の作成
以下のssh-keygenコマンド（SSHクライアントのコマンド）を使います。
```
ssh-keygen -y -f \path\to\your\pem-key.pem
```
Windows の場合、PowerShellが必要です。~~linux みたいなコマンドが叩けるコマンドプロンプトの進化版みたいなやつです。~~
<br>
※2025/3/28追記
Windowsでは、上記ssh-keygenコマンドを使用するためにWSLが必要です。ここでは、WSLとWSL上で動くLinuxディストリビューション（Ubuntu 24.04など）をインストールしている前提で書いています。PowerShell上で、以下のコマンドを使用するとWSLターミナルを開くことができます。
```
wsl -d Ubuntu-24.04
```

<br>

公開鍵 ~~じたい~~ はとても長い文字列がコマンドプロンプト上に直で出力されます。 ~~こんな感じ~~。

<br>

```
ssh-rsa srryeahu6auzjzhtsjssssssfds3/afeayrkias7k.......
```

## Linuxユーザーの作成と公開鍵の追加
以下のコマンドを実行します。
```
sudo adduser newuser(ユーザー名)
sudo su - newuser
mkdir .ssh
chmod 700 .ssh
touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
vi .ssh/authorized_keys
```

<br>

* `sudo su - newuser` は、ユーザーを新しく作ったnewuser(SSH用ユーザー)に切り替えます。（ハイフンはLinuxのログイン時に環境設定ファイルを読み込むという意味）

<br>

* `chmod 700 .ssh` は、公開鍵ファイルを作成する親ディレクトリの権限をSSH用ユーザーだけに与えるということです。
* `chmod 600 .ssh/authorized_keys` は、同じく公開鍵ファイルに対して、書き込みと読み取り権限だけをSSH用ユーザーだけに与えるということです。

<br>

上記の最後のコマンドで作成した ` authorized_keys ` ファイルに
コマンドプロンプトに出力された公開鍵(長い文字列)をコピーして保存します。(Viエディタで、`i` -> `右クリックでペースト` -> `Esc` -> `:wq` と入力。)
```.ssh/authorized_keys
ssh-rsa srryeahu6auzjzhtsjssssssfds3/afeayrkias7k.......
```

### 既存の公開鍵が登録されていなく、シェルにアクセスできない場合
※2025/3/28追記
<br>
まだ公開鍵が一つも登録されておらず、リモートにSSHで直接アクセスができない場合、以下のようにローカルから公開鍵をリモートに追加することもできます。
<br>
まず前準備として、以下をおこないます。
```
# ssh-agentを起動
$ eval `ssh-agent`
Agent pid 4562

# ローカル側で公開鍵を登録
$ ssh-add ~/.ssh/id_ed25519
Identity added: /home/username/.ssh/id_ed25519
```

<br>公開鍵の中身の文字列を取得しておきます。
<br>

```
$ cat ~/.ssh/id_ed25519.pub
```

### AWS（EC2）にSSH接続する場合のみ以下をおこなう
<br>この節では、シェルにアクセスできない、かつAWSを利用してEC2インスタンスに公開鍵認証方式でSSH接続したい場合について書いています。
<br>下記のリンクを参考に、AWSマネジメントコンソールを使用してEC2 Linux インスタンスに SSH アクセスを持つ新しいユーザーアカウントを追加します。また、上記で取得した公開鍵の文字列をリンク先の手順に従ってリモート側にコピペします。
<br>

https://repost.aws/ja/knowledge-center/ec2-user-account-cloud-init-user-data

```
# ルートユーザーでSSHでシェルにアクセスできる場合（コマンドは同一のものを再掲）

# 新しいユーザーの追加
sudo adduser newuser(ユーザー名)
sudo su - newuser

# 公開鍵を格納するディレクトリの作成と権限の付与
mkdir .ssh
chmod 700 .ssh

# 公開鍵を貼り付けるファイルの作成と権限の付与
touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

# エディタで直接ファイルを開き、公開鍵を貼り付ける
vi .ssh/authorized_keys
```

ただし、本節ではシェルアクセスできない前提なので、この公開鍵を追加する方法は実行不可能です。パスワード認証方式がデフォルトで無効になっているAWSのインスタンスにはSSHで接続できず、公開鍵を直接追加できません。つまり、公開鍵を格納するディレクトリの作成以降の手順を踏んで公開鍵を追加することができません。
<br>普通、AWSの場合はシステムユーザー（Amazon Linux 2や 2023はec2-user）用の初期キーペアを生成しておけば、システムユーザーでSSHでシェルにアクセスしてユーザーアカウントや公開鍵をリモートのEC2インスタンスに追加することができると思われます。その場合、システムユーザーでリモートに対してSSH接続します。そのうえで、本章で書いているadduserコマンドを使用してユーザーを追加し、上記でローカルで取得した公開鍵の文字列を.ssh/authorized_keysにコピペすることで公開鍵を追加することができます。
<br>ですが、たとえばシステムユーザー用の初期キーペアを紛失した状態で、新しいキーペアを作成し、ssh-keygenで生成した公開鍵を登録しようとしてもシェルでは直接登録することはできません。おそらくですが、新しいユーザーに対してキーペアや公開鍵を追加する場合は、システムユーザーでのアクセスが前提となっていると思います。システムユーザー用の初期キーペアを紛失した場合、[「SSH キーペアを紛失した場合、Amazon EC2 インスタンスに接続する方法を教えてください」](https://repost.aws/knowledge-center/user-data-replace-key-pair-ec2)の手順に従って、回復することが必要だと思われます。AWSのマネジメントコンソール（[EC2](https://console.aws.amazon.com/ec2/) Instance Connect）で、紛失したキーの公開鍵を再度登録し直せるようになっています。詳しい手順は省略しますが、上記リンクの手順を見れば簡単にできます。EC2 Instance Connectを使用してブラウザからシェルにアクセスする方法は以下のリンクに書いてありました。
<br>
[EC2 Instance Connect を使用して Linux インスタンスに接続する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-connect-methods.html)

### Linuxのサーバーなど（接続先がAWSではないサーバー）の場合
ssh-copy-idというコマンドを使用してローカルからリモートに公開鍵をコピーする方法もあります。SSHで接続するサーバーがAWSではない場合、このコマンドでも公開鍵をローカルから追加することができるようです。
<br>ですが、AWSではパスワード認証がデフォルトで無効になっているため、ssh-copy-idを使ってリモートにアクセスしようとすると、以下のような「Permission denied」というメッセージが表示され、公開鍵を追加できません。

```
$ ssh-copy-id -i id_ed25519.pub ec2-user@ec2-12-34-567-789.ap-northeast-1.compute.amazonaws.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ec2-user@ec2-12-34-567-789.ap-northeast-1.compute.amazonaws.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

なお、SSHの認証方式については以下のリンクを参照してください。

https://qiita.com/lucifer22/items/b60c6f5d7ff2077fe599#2-ssh%E3%81%AE%E8%AA%8D%E8%A8%BC%E6%96%B9%E6%B3%95%E5%85%AC%E9%96%8B%E9%8D%B5%E8%AA%8D%E8%A8%BC%E3%81%AE%E6%A6%82%E8%A6%81

これで~/.ssh/authorized_keysに公開鍵が追加されます。
<br>

# IAMでEC2にSSH接続する注意点
AWS特有の注意ポイントです。
## EC2コンソールで作ったpemファイルの権限
公開鍵を作るときに、pemファイルの権限が誰でも閲覧可だと以下のようなエラーになります。
`WARNING: UNPROTECTED PRIVATE KEY FILE!`

これを防ぐには、Windowsの場合はファイルをエクスプローラーで右クリックしたメニューから、
所有者を自分にして、読み取り権限のみを付与します。
詳しい手順は参考サイトにある「インスタンスへの接続に関するトラブルシューティング」の ` エラー: Unprotected Private Key File (保護されていないプライベートキーファイル) ` の項に書いてます。
Linux コマンドでは ` chmod 0400 .ssh/my_private_key.pem ` を実行することと同じです。



# 参考サイト
https://qiita.com/aiandrox/items/98ad9b7551481d890916#ec2%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AE%E4%B8%AD%E3%81%A7%E8%A1%8C%E3%81%86%E6%8E%A8%E5%A5%A8%E8%A8%AD%E5%AE%9A

https://qiita.com/leomaro7/items/662699dcb7a7adc36f40

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/managing-users.html

### 【2025/6/8 追記】補足_Ubuntuの場合
Ubuntuの場合は[Ubuntu Server の公式ドキュメント](https://documentation.ubuntu.com/server/how-to/security/openssh-server/index.html) が参考になります。タイトルからは少し外れますが、AWS以外にUbuntuをいじることがあったので、備忘録的に。