SSH関連の頻出コマンドと周辺知識まとめ

注：本記事のコマンド、説明は筆者のM1Macにより動作が確認できたものになります。

# 公開鍵暗号方式キーペアの作成方法
以下のコマンドでキーペアを作成できます。
```sh 
ssh-keygen -t rsa -f anyfilename
```

このコマンドは、RSAタイプのキーペアを生成し、anyfilenameという名前のファイルに保存します。キーペアの生成後、公開鍵（anyfilename.pub）をリモートサーバー（例：GitHub）に登録し、秘密鍵（anyfilename）を安全な場所に保管します。

# .ssh/ディレクトリ
作成したキーペアは、`.ssh/`ディレクトリに置くことが多いようです。

- ディレクトリ構造とパーミッション
    - .ssh ディレクトリはユーザーのホームディレクトリに通常配置され、SSH関連のファイル（秘密鍵、公開鍵、configファイルなど）を保存します。このディレクトリとその中のファイルのパーミッション設定が重要であり、通常はディレクトリには 700（所有者のみ読み書きき、実行可能）、ファイルには 600（所有者のみ読み書き可能）のパーミッションを設定するのが一般的です。これにより、他のユーザーからの不正なアクセスを防ぎます。

:::note warn
### WARNING: UNPROTECTED PRIVATE KEY FILE!
このエラーメッセージは、SSHのプライベートキーのパーミッション（許可）が緩すぎるという問題を示しています。SSHのプライベートキーは秘密情報であり、他のユーザーによるアクセスを制限する必要があります。SSHは、プライベートキーが安全でないと判断すると、そのキーを使用しません。

この問題を解決するには、プライベートキーのパーミッションを変更して、ファイルが他のユーザーによって読み取り可能でないようにする必要があります。ターミナルで次のコマンドを実行して、プライベートキーのパーミッションを変更します。

```sh
chmod 600 ~/.ssh/any_key_rsa
```

このコマンドは、プライベートキー`~/.ssh/any_key_rsa`のパーミッションを`600`に設定します。これにより、ファイルの所有者のみが読み書きできるようになり、他のユーザーはアクセスできなくなります。

パーミッションを変更した後、再度リモートリポジトリにアクセスしてみてください。これでエラーが解消されるはずです。
:::

# configファイル
特定のホストとSSH通信する時に、どの秘密鍵を使用すれば良いかの情報を`=/.ssh/config`に記述します。

下記はCodeCommitの秘密鍵情報を記述する例です。

```
Host git-codecommit.*.amazonaws.com
  User <your-iam-ssh-key-id> # AWS IAMで生成したSSHキーのIDに置き換えてください。
  IdentityFile ~/.ssh/codecommit
```

下記のように`~/.ssh/config`ファイルに直接書き込まずに、他ファイルから設定を`Include`するやり方もあります。

```config: ~/.ssh/config
Include ~/.ssh/conf/hogehoge_proj
Include ~/.ssh/conf/uhouho_proj
```

:::note note
### デフォルト動作について
SSH通信を行う際、`~/.ssh/config`ファイルに特定の通信先に関する設定がない場合、SSHはデフォルトの動作に従います。具体的には、SSHは通常、以下のデフォルトの秘密鍵ファイルを探します。

- `~/.ssh/id_rsa` （RSAキー）
- `~/.ssh/id_dsa` （DSAキー）
- `~/.ssh/id_ecdsa` （ECDSAキー）
- `~/.ssh/id_ed25519` （Ed25519キー）

これらのファイルは、SSHクライアントがデフォルトで探しに行く秘密鍵です。したがって、これらの名前で秘密鍵を保存しておけば、特に~/.ssh/config ファイルに設定を追加しなくてもSSH通信に使用されます。
:::

# known_hostsファイル
`~/.ssh/known_hosts`は、SSHクライアントが接続したリモートサーバの公開鍵を保存するファイルです。
過去に接続したことのあるリモートサーバに再度SSH接続を行う際、リモートサーバの公開鍵情報が`~/.ssh/known_hosts`内に存在していればサーバの正当性が確認できるため、安全に接続が行えます。

`~/.ssh/known_hosts`は以下のような構成で記載されています。
```
[ホスト名1/IPアドレス],[別の名前1/IP] ssh-key-type ホストキー（公開鍵）
[ホスト名2/IPアドレス],[別の名前2/IP] ssh-key-type ホストキー（公開鍵）
```

```text:具体例
github.com,192.30.255.113 ssh-rsa AAAABBBB333NN...
hogehoge.com,121.00.144.144 ssh-rsa BBBDDD7777nnCn...
```

:::note info
### 特定のリモートサーバに初めて接続する場合

SHを介してリモートサーバに初めて接続する際には、SSHクライアントがそのサーバの公開鍵をまだ認識していないため、特定の警告メッセージが表示されます。このメッセージは、ユーザーにリモートホストの身元を確認し、信頼できるかどうかを判断させるためのものです。

警告メッセージは通常、以下のような内容を含みます：

```shell
The authenticity of host '[hostname] ([IP address])' cant be established.
[Key type] key fingerprint is [fingerprint].
Are you sure you want to continue connecting (yes/no)?
```
メッセージには、リモートホストの公開鍵の指紋（またはハッシュ）が表示され、ユーザーに対してそのホストを信頼して接続を続行するかどうかを尋ねています。

この段階で「yes」と答えると、そのホストの公開鍵が`~/.ssh/known_hosts`ファイルに追加され、今後そのホストに接続する際にはこの警告は表示されません。ただし、安全性を確保するためには、表示された公開鍵の指紋が実際のリモートホストのものと一致することを確認することが重要です。これにより、中間者攻撃のリスクを避けることができます。
:::

:::note info
### ホストキー（公開鍵）収集&追加コマンド
以下のコマンドで、あらかじめknown_hostsファイルにリモートサーバの公開鍵を追加できます。

```
$ ssh-keyscan git-codecommit.<region>.amazonaws.com >> ~/.ssh/known_hosts
```

※ 上記はAWS CodeCommitへのアクセス情報を追加する際の例です。`<region>`は、CodeCommitリポジトリが存在するAWSリージョンに置き換えてください。
:::

:::note warn
### WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
特定のリモートサーバにアクセスした際に返された公開鍵情報が、`~/.ssh/known_hosts`に登録されている公開鍵と一致しない場合に返される警告です。
:::