最低限のセキュアなSSH接続

安全にssh接続をするために、行う設定をまとめました。後で自分自身が見返せるように作成しました。

環境といたしましては、
`client`：Windows11
`host`：Ubuntu22.0.4.1LTS

前提として`root`以外ユーザーでログインします。

# 公開鍵暗号方式とは

公開鍵暗号方式を簡単に説明すると、次のようなイメージです。

![段落テキスト-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789749/0dfb4fd3-1506-cb9f-2d93-53b78943ac8e.png)


まず、自分専用の「暗号をかける魔法」と「暗号を解く魔法」を準備します。このうち、「暗号をかける魔法」をみんなに公開します。みんなはその魔法を使って、あなた宛てのメッセージを安全に暗号化して送ります。

「暗号を解く魔法」は誰にも教えない秘密の魔法です。

そして、あなただけが知っている秘密の「暗号を解く魔法」を使って、送られてきたメッセージを読み解きます。

これで誰でも暗号化はできるけど、**解けるのはあなた専用の魔法だけ**という仕組み。

---
### イメージで覚える
- `暗号をかける魔法`：公開鍵　👨‍👨‍👧‍👦🪄🔒
- `暗号を解く秘密の魔法`：秘密鍵　🧙‍♂️🪄🔓
---


# SSH Keyの作成

これからは実際にクライアント側（私の環境はWindows11）で以下のコマンドを実行し、`公開鍵`と`暗号化`を作成していきましょう。
今回は、計算効率が高くセキュリティレベルの高い`Ed25519`アルゴリズムを使用していきたいと思います。

```
ssh-keygen -t ed25519
```
:::note warn
Windowsを利用する場合
`ssh-keygen`はOpenSSHクライアントのインストールが必要になります。インストールがまだの際は、以下の手順でインストールしてください

設定を開く
- システム
    - オプション機能をクリック
        - 機能の表示
            - OpenSSHクライアントを追加
:::


**レスポンスとして、以下の2つが聞かれると思います。**
```
Enter file in which to save the key (C:\Users\211111/.ssh/id_ed25519):
```
- 最初の質問はどこにキーペアを保存しますか？と聞かれています。デフォルトですとユーザーディレクトリ直下の`/.ssh/`の中に保存されるので、特に問題ない人はそのまま`Enter`

```
Enter passphrase (empty for no passphrase):
```
- これは`パスフレーズ`を設定するか聞かれています。よりセキュアな接続がしたい方は設定しましょう。設定すると再度聞かれるので、同じパスフレーズを入力します
- 設定しない方はそのまま`Enter`

実際にディレクトリを`/.ssh`に移動して`ls`し、作成されているか見てみましょう。
```
PS C:\Users\ms211111\.ssh> ls

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2025/01/21     16:33            411 id_ed25519
-a----        2025/01/21     16:33            100 id_ed25519.pub
```
- `id_ed25519.pub`：公開鍵　👨‍👨‍👧‍👦🪄🔒
- `id_ed25519`：秘密鍵　🧙‍♂️🪄🔓

`id_ed25519`は自分だけの秘密なものなので**共有してはいけません**

## 公開鍵の共有
次に作成した`公開鍵`をサーバー（ホスト）の方に共有していきます。
やり方が大きく3つあるのでそれぞれ紹介していきます。

- `ssh-copy-id`を利用する方法
```
ssh-copy-id -i <公開鍵のファイル名> <ユーザー名>@<IPv4アドレス>

#例
ssh-copy-id -i id_ed25519.pub test@192.168.1.1
```
これが一番簡単で効率的なやり方です。
ssh-copy-id コマンドは、ローカルの公開鍵をリモートサーバーの authorized_keys に簡単に追加するための標準的な方法ですが、`現在Windowsでは実行不可`（WSLでならいけるかも？）

- `scp`を利用する方法
```
scp <公開鍵のファイル名> <ユーザー名>@<IPv4アドレス>:<公開鍵の保存先>

#例
scp id_ed25519.pub test@192.168.1.1:/tmp/id_ed25519.pub
cat /tmp/id_ed25519.pub >> ~/.ssh/authorized_keys
rm /tmp/id_ed25519.pub
```
もしファイル転送を使いたい場合、`scp`コマンドで公開鍵ファイルをリモートサーバーにコピーし、その後リモートで追加することもできます。
その後、実行例の2行目以降のようにリモートサーバーで公開鍵を authorized_keys に追加します。

:::note info
linuxのディレクトリ
`tmp`ディレクトリとは一時的なファイル置き場なので、利用した後は削除しましょう。
:::


- `手動`で追加する方法
```
#公開鍵の中身を確認
cat <公開鍵のファイル)>

#リモート接続
ssh <ユーザー名>@<IPv4アドレス>

#catで確認した公開鍵の中身を追加
echo "<公開鍵の内容>" >> ~/.ssh/authorized_keys

#例
cat id_ed25519.pub
ssh test@192.168.1.1
echo "<公開鍵の内容>" >> ~/.ssh/authorized_keys
```
最終手段となりますが、この方法であれば、公開鍵の内容をコピーして直接追加できます。

:::note warn
`.ssh/authorized_keys`がホームディレクトリにない場合
作成する必要があります。
```
mkdir ~/.ssh
touch ~/.ssh/authorized_keys
```
この次の注意事項も実行してください。`権限の変更`
:::

:::note warn
`authorized_keys`がない、または権限がない際
権限の変更を行います。
```
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
```
:::

ファイルまたはディレクトリの権限が以下のようになっていたら大丈夫です。
権限の設定が違う際は、上記の「`authorized_keys`がない、または権限がない際」を参照してください。
```
drwx------ 2 test test   4096 Jan 20 22:06 .ssh
-rw------- 1 test test 205 Jan 21 10:14 authorized_keys
```

# 公開鍵認証のみ許可
セキュリティを強化するために、パスワード認証が無効化、つまり、公開鍵認証のみでSSH接続するように設定を変更します。

まず、SSH サーバーの設定ファイルを編集します。通常、設定ファイルは `/etc/ssh/sshd_config` にあります。

```
#お好きのエディタで今回はvimで
sudo vim /etc/ssh/sshd_config
```
編集モードに入り以下のコメントアウトを探します。
```
#PasswordAuthentication yes
```
見つけたら、上記のコメントアウトされた行を削除し、次の行を追加します。
```
PasswordAuthentication no
ChallengeResponseAuthentication no
```
- `PasswordAuthentication no `はパスワード認証を無効にします
- `ChallengeResponseAuthentication no `は、パスワードやその他のチャレンジレスポンス認証を無効にします

以下のコメントアウトを探して、コメントアウトを解除します。
```
PubkeyAuthentication yes
```
- `PubkeyAuthentication yes`は公開鍵認証を必須にする設定です
これにより、パスワードを使ったログインを完全に防げます

最後に以下のコマンドを実行して、設定に問題がないか確認します。何もレスポンスが返ってこない場合成功となります。
```
sudo sshd -t
```
問題がなかったら、SSH サーバーを再起動して変更を反映させます。
```
sudo systemctl restart sshd
```

:::note info
Vimのざっくりとした使い方
`i`：インサートモードに移行、ファイルの内容を変更できます。
`Escキー`:インサートモードから出られる
`:wq`:保存してからVimを閉じる
:::

:::note info
ポート番号の変更
SSH接続はデフォルトでは`22番ポート`ですが変更することができます。
```
Port 22
↓
Port <任意ポート>
```
注意事項
- 変更する際はウェルノウンポートを避けて変更しましょう
- また、特定のサービスを利用している際は競合しないようなポート選びをしましょう
:::note alert
`ファイアウォール`で事前に<任意のポート>は開ける。
一番安全なのは`Port22`は残したままで`Port<任意ポート>`を追加して、任意のポートで接続できた後に`Port22`を削除する
:::


# SSH接続する
PowerShellから先ほど設定したサーバーに接続してみたいと思います。
```
ssh -i <秘密鍵のパス> <ユーザー名>@<IPv4アドレス>

#例
ssh -i ~/.ssh/id_ed25519 test@192.168.1.1
```
無事に接続できると成功です。

::: note info
オプション機能
`-i`は指定したプライベートキーを使って認証を行う ことを意味します。
:::


また、パスワード認証が無効化されているか確認してみましょう。

```
ssh <ユーザー名>@<IPv4アドレス>

#例
ssh test@192.168.1.1
```
レスポンスとして以下の内容が返ってきて、パスワードを求められなければ成功です。
```
test@192.168.1.1: Permission denied (publickey).
```
お疲れ様でした！！！

# 最後に
公開鍵認証方式を使用することで、パスワード認証が不要になり、パスワードを介した攻撃（例えばブルートフォース攻撃や辞書攻撃）のリスクを大幅に低減できる点が非常に大きいです。これにより、セキュリティが格段に強化されます。
また、余力がある際はSSHのポート変更もやってみてください。その際はufwなどのファイアウォールでポート開放することをお忘れなく。