ローカル端末のみに秘密鍵を保持：SSH Agent Forwardingによる安全な多段SSH接続

# 1. 背景
パブリックサブネットにある踏み台サーバー（`Bastion Server`）経由で他のサーバーにアクセスする際、プライベートキー（`private key`）はどう管理していますか？
たまにプライベートキーを`Bastion Server`に置いてしまうケースを聞いたことがあります。
しかし、これは非常に危険な方法です。
プライベートキーを`Bastion Server`に置くと、そのサーバーが侵害された場合、プライベートサブネット内の他のEC2インスタンスも危険にさらされる可能性があります。このリスクを回避するため、より安全な方法を検討する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/e75917f4-3f76-0dc8-9b7b-ed37fd01b29a.png)

そこで、`Bastion Server`やプライベートEC2インスタンスに直接プライベートキーをコピーせず、ローカルマシンにのみプライベートキーを保存する`SSH Agent Forwarding`方式について説明します。この方法を使用することで、セキュリティを向上させつつ、効率的にサーバーアクセスを行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/2238a814-321a-81ad-bdc9-92006f37c54a.png)


# 2. SSH Agent Forwardingの動作仕組み
## 2.1 操作プロセス
1. 接続の確立
   ローカルマシンからBastion Serverに接続する際、SSH AgentのUNIXドメインソケットが転送
1. 認証要求の転送:
   Bastion ServerからPrivate EC2インスタンスに接続する際、認証要求がSSHプロトコルを通じてローカルマシンのSSH Agentに転送されます
1. ローカルでの署名:
   <font color="red">ローカルマシンのSSH Agentが秘密鍵を使用して認証要求に署名し、結果を転送</font>
1. 認証の完了:
   署名された認証要求がBastion Serverを経由してPrivate EC2インスタンスに送られ、認証が完了

## 2.2 特徴
- <font color="red">秘密鍵はローカルマシンから移動しません</font>
- <font color="red">中間サーバー（Bastion Server）に秘密鍵をコピーする必要がありません</font>
- 複数のホップを経由する場合でも、1つの秘密鍵で認証が可能


https://qiita.com/slotport/items/e1d5a5dbd3aa7c6a2a24


# 3. 利用ための準備
1. SSHクライアント側(Bastion Serverにログインするローカルマシン)`Agent Forwarding`の有効化
    1. `ssh -A`コマンドで都度指定する方法
        ```
        ssh -A ec2-user@bastion-server-ip
        ```
    1. ユーザーの`~/.ssh/config`で設定を追加する方法
        ```
        Host *
          ForwardAgent yes
        ```

3. Bastion Server側`Agent Forwading`の有効化：
    - Bastion ServerのSSHDの設定ファイル（`/etc/ssh/sshd_config`）で、以下の設定が有効になっていることを確認
        ```
        AllowAgentForwarding yes
        ```
    ::: note info
    1. 多くのLinuxのデフォルト設定では、`/etc/ssh/sshd_config`の`AllowAgentForwarding`がコメントアウトされたとしても、デフォルトで`yes`として扱われます。つまり、明示的にnoと設定されていない限り、Agent Forwardingは許可されています。
    つまり、<font color="red">Bastion Server側で明示的にAgent Forwardingを有効にする設定を行わなくても、クライアント側の設定が正しければAgent Forwardingは機能</font>します。
    
    2. 現在の設定を確認する方法：
    ```
    sudo sshd -T | grep -i 'AllowAgentForwarding'
    ```
    現在bastion server側の設定値を確認：デフォルトで`yes`になっている
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/0b776095-70dc-464e-272e-137ce063fb80.png)

https://qiita.com/akase244/items/d640cb2235bc0995bd87

# 4. `ssh -A`コマンドで都度指定する方法
:::note info
事前準備：ローカルPCの.ssh/configに以下を設定しておく
```
Host bastion
  Hostname <bastion-server-ip>
  Port 22
  User ec2-user
  IdentityFile ~/.ssh/id_rsa
```
:::

- ローカルPCから以下のコマンドで先にbastionサーバーにアクセス
    ```
    $ ssh -A bastion
    ```
- さらにbastionサーバーからprivate subenetにあるEC2にログイン
    ```
    $ ssh ec2-user@<private-instance-ip>
    ```
# 5. ユーザーの`~/.ssh/config`で設定を追加する方法

:::note info 
事前準備：`/.ssh/config`ファイルに以下の内容を設定しておく
```
Host bastion
  Hostname <bastion-server-ip>
  Port 22
  User ec2-user
  IdentityFile ~/.ssh/id_rsa
  ForwardAgent yes

Host private
  Hostname <private-instance-ip>
  Port 22
  User ec2-user
  ProxyCommand ssh -W %h:%p bastion
```
:::

- ローカルPCから以下のコマンドで先にbastionサーバーにアクセス
    ```
    $ ssh bastion
    ```
- ローカルPCからprivate subenetのEC2にログイン
    ```
    $ ssh private
    ```