OpenSSHの鍵交換をmlkem768x25519-sha256にする

# 前書き

- OpenSSHバージョン10.0の導入とML-KEMによる鍵交換の保護の設定を扱う
- 環境はUbuntu 24.04 LTS

# 1. インストール

## 1-1. LibreSSL 4.0.0 インストール

```terminal:LibreSSLインストール
$ cd /opt/src
$ curl -OL https://github.com/libressl/portable/releases/download/v4.0.0/libressl-4.0.0.tar.gz
$ tar zxf libressl-4.0.0.tar.gz
$ cd libressl-4.0.0/
$ ./configure --prefix=/opt/libressl-4.0.0
$ make
$ doas make install
$ /opt/libressl-4.0.0/bin/openssl version
LibreSSL 4.0.0
```

## 1-2. OpenSSH 10.0 インストール

```terminal:OpenSSHインストール
$ cd /opt/src
$ curl -L -o openssh-10.0p2.tar.gz https://github.com/openssh/openssh-portable/archive/refs/tags/V_10_0_P2.tar.gz
$ tar zxf openssh-10.0p2.tar.gz
$ cd openssh-portable-V_10_0_P2
$ ./configure --prefix=/opt/openssh-10.0p2 \
> --with-ssl-dir=/opt/libressl-4.0.0 \
> --with-cppflags=-I/opt/libressl-4.0.0/include \
> --with-ldflags=-Wl,-rpath,/opt/libressl-4.0.0/lib
$ make
$ doas make install
$ /opt/openssh-10.0p2/bin/ssh -V
OpenSSH_10.0p2, LibreSSL 4.0.0
$ /opt/openssh-10.0p2/sbin/sshd -V
OpenSSH_10.0p2, LibreSSL 4.0.0
```

# 2. ssh_config設定

AWSの下記サイトとか参考にしつつ

https://docs.aws.amazon.com/transfer/latest/userguide/security-policies.html

| ディレクティブ | 有効にするもの |
|:-|:-|
| KexAlgorithms | mlkem768x25519-sha256 |
| Ciphers | aes256-gcm[]()@openssh.com |
| MACs | hmac-sha2-512-etm[]()@openssh.com |
| HostKeyAlgorithms | デフォルト設定値のまま |
| PubkeyAcceptedAlgorithms | デフォルト設定値のまま |
| RequiredRSASize | 2048 |


## 2-1. ssh_config: KexAlgorithms

```terminal:使えるもの
$ /opt/openssh-10.0p2/bin/ssh -Q kex
diffie-hellman-group1-sha1
diffie-hellman-group14-sha1
diffie-hellman-group14-sha256
diffie-hellman-group16-sha512
diffie-hellman-group18-sha512
diffie-hellman-group-exchange-sha1
diffie-hellman-group-exchange-sha256
ecdh-sha2-nistp256
ecdh-sha2-nistp384
ecdh-sha2-nistp521
curve25519-sha256
curve25519-sha256@libssh.org
sntrup761x25519-sha512
sntrup761x25519-sha512@openssh.com
mlkem768x25519-sha256
```

```terminal:ssh_config KexAlgorithms設定
$ doas sed -i -e '$aKexAlgorithms mlkem768x25519-sha256' /opt/openssh-10.0p2/etc/ssh_config
```

## 2-2. ssh_config: Ciphers


```terminal:使えるもの
$ /opt/openssh-10.0p2/bin/ssh -Q ciphers
3des-cbc
aes128-cbc
aes192-cbc
aes256-cbc
aes128-ctr
aes192-ctr
aes256-ctr
aes128-gcm@openssh.com
aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
```

```terminal:ssh_config Ciphers設定
$ doas sed -i -e '$aCiphers aes256-gcm@openssh.com' /opt/openssh-10.0p2/etc/ssh_config
```

## 2-3. ssh_config: MACs

```terminal:使えるもの
$ /opt/openssh-10.0p2/bin/ssh -Q macs
hmac-sha1
hmac-sha1-96
hmac-sha2-256
hmac-sha2-512
hmac-md5
hmac-md5-96
umac-64@openssh.com
umac-128@openssh.com
hmac-sha1-etm@openssh.com
hmac-sha1-96-etm@openssh.com
hmac-sha2-256-etm@openssh.com
hmac-sha2-512-etm@openssh.com
hmac-md5-etm@openssh.com
hmac-md5-96-etm@openssh.com
umac-64-etm@openssh.com
umac-128-etm@openssh.com
```

```terminal:ssh_config MACs設定
$ doas sed -i -e '$aMACs hmac-sha2-512-etm@openssh.com' /opt/openssh-10.0p2/etc/ssh_config
```

## 2-4. ssh_config: RequiredRSASize

デフォルト値: 1024

```terminal:ssh_config RequiredRSASize設定
$ doas sed -i -e '$aRequiredRSASize 2048' /opt/openssh-10.0p2/etc/ssh_config
```

# 3. sshd_config設定

| ディレクティブ | 有効にするもの |
|:-|:-|
| KexAlgorithms | mlkem768x25519-sha256 |
| Ciphers | aes256-gcm[]()@openssh.com |
| MACs | hmac-sha2-512-etm[]()@openssh.com |
| HostKeyAlgorithms | デフォルト設定値のまま |
| PubkeyAcceptedAlgorithms | デフォルト設定値のまま |
| RequiredRSASize | 2048 |


## 3-1. sshd_config: KexAlgorithms

```terminal:初期状態
$ doas /opt/openssh-10.0p2/sbin/sshd -T | sed -n -e '/^kexalgorithms /s/,/\n/gp'
kexalgorithms mlkem768x25519-sha256
sntrup761x25519-sha512
sntrup761x25519-sha512@openssh.com
curve25519-sha256
curve25519-sha256@libssh.org
ecdh-sha2-nistp256
ecdh-sha2-nistp384
ecdh-sha2-nistp521
```

```terminal:sshd_coonfig KexAlgorithms設定
$ doas sed -i -e '$aKexAlgorithms mlkem768x25519-sha256' /opt/openssh-10.0p2/etc/sshd_config
$ doas /opt/openssh-10.0p2/sbin/sshd -T | grep kexalgorithms
kexalgorithms mlkem768x25519-sha256
```

## 3-2. sshd_config: Ciphers

```terminal:初期状態
$ doas /opt/openssh-10.0p2/sbin/sshd -T | sed -n -e '/^ciphers /s/,/\n/gp'
ciphers chacha20-poly1305@openssh.com
aes128-gcm@openssh.com
aes256-gcm@openssh.com
aes128-ctr
aes192-ctr
aes256-ctr
```

```terminal:sshd_coonfig Ciphers設定
$ doas sed -i -e '$aCiphers aes256-gcm@openssh.com' /opt/openssh-10.0p2/etc/sshd_config
$ doas /opt/openssh-10.0p2/sbin/sshd -T | grep '^ciphers '
ciphers aes256-gcm@openssh.com
```

## 3-3. sshd_config: MACs

```terminal:初期状態
$ doas /opt/openssh-10.0p2/sbin/sshd -T | sed -n -e '/^macs /s/,/\n/gp'
macs umac-64-etm@openssh.com
umac-128-etm@openssh.com
hmac-sha2-256-etm@openssh.com
hmac-sha2-512-etm@openssh.com
hmac-sha1-etm@openssh.com
umac-64@openssh.com
umac-128@openssh.com
hmac-sha2-256
hmac-sha2-512
hmac-sha1
```

```terminal:sshd_coonfig MACs設定
$ doas sed -i -e '$aMACs hmac-sha2-512-etm@openssh.com' /opt/openssh-10.0p2/etc/sshd_config
$ doas /opt/openssh-10.0p2/sbin/sshd -T | grep '^macs '
macs hmac-sha2-512-etm@openssh.com
```

## 3-4. sshd_config: RequiredRSASize

```terminal:初期状態
$ doas /opt/openssh-10.0p2/sbin/sshd -T | grep requiredrsasize
requiredrsasize 1024
```

```terminal:sshd_coonfig RequiredRSASize設定
$ doas sed -i -e '$aRequiredRSASize 2048' /opt/openssh-10.0p2/etc/sshd_config
$ doas /opt/openssh-10.0p2/sbin/sshd -T | grep requiredrsasize
requiredrsasize 2048
```

# 4. 既存sshdから新sshdへの移行

## 4-1. 移行用のsshd起動

```terminal:移行用sshd起動
$ doas /opt/openssh-10.0p2/sbin/sshd -t
$ doas /opt/openssh-10.0p2/sbin/sshd -p 10022
```

## 4-2. 移行用のsshへの接続切り替え

- 移行用のsshdへ接続する
  - sshクライアントは`KexAlgorithms mlkem768x25519-sha256`に対応していなければならない
  - Windowsではputtyはバージョン0.83は少なくとも対応済、teratermは最新版5.4.0でも未対応
  - macOSはバージョン15.4.1で標準のOpenSSHが対応済
- 動作テストに問題なければ、既存のssh接続を切断し、移行用sshdへの接続に切り替える


## 4-3. 既存のsshd停止

```terminal:sshd停止
$ doas systemctl stop ssh.socket
$ doas systemctl disable ssh.service
```


## 4-4. 新sshdサービス起動設定

```terminal:systemdサービス設定作成
$ cat /usr/lib/systemd/system/ssh.service
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service
$ sed -e 's|/usr/sbin/sshd|/opt/openssh-10.0p2/sbin/sshd|' -e '$d' /usr/lib/systemd/system/ssh.service | doas tee /etc/systemd/system/ssh10.service
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/opt/openssh-10.0p2/sbin/sshd -t
ExecStart=/opt/openssh-10.0p2/sbin/sshd -D $SSHD_OPTS
ExecReload=/opt/openssh-10.0p2/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
```

## 4-5. 新sshdサービス有効化

```terminal:systemdサービス有効化
$ doas systemctl start ssh10.service
$ systemctl status ssh10.service --no-pager
$ doas systemctl enable ssh10.service
$ systemctl status ssh10.service --no-pager
```

## 4-6. 新sshdへ接続切替

- 新sshdへ接続する
- 動作テストに問題なければ、移行用sshへの接続を切断する


## 4-7. 移行用sshdを停止

```terminal:移行用sshd停止
$ doas kill $(doas ss -tnlp | sed -n -e '/0.0.0.0:10022/s/^.*,pid=\(.*\),fd=.*$/\1/p')
$ doas ss -tnlp | grep 10022
```


# 5. sshコマンドの切り替え

```terminal:デフォルトのssh関連コマンドPATH設定
$ echo 'export PATH=/opt/openssh-10.0p2/bin:$PATH' | doas tee /etc/profile.d/Z99-ssh10-path.sh
```


おしまい

# Footer

## 仲間を募集しています！

ARIではエンジニア・ITコンサルタント・PM職全方位で仲間を募集しております。
カジュアル面談、随時受付中です！
ご興味ある方はこちらをご覧ください。

https://note.com/ari_hr/n/n4aed9ba75421