背景
OpenSSH 8.2からU2F/FIDO2デバイスを用いたハードウェア認証に対応しており、仮に秘密鍵が漏洩しても鍵の生成時に利用したデバイス(Yubikeyなど)がないとsshできなくなるというセキュアな対応が実現できます。
以前はOpenPGPに委譲させたり、PIVで対応するといった選択肢がありましたが、それぞれ設定がやや大変だったのでこの対応は非常に嬉しいです。
環境
OpenSSH 8.2以上のサーバー・クライアントが必要です。
事前準備
Ubuntu側
$ vagrant init ubuntu/focal64
簡単のためローカルIPを設定します。
# Create a private network, which allows host-only access to the machine # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" + config.vm.network "private_network", ip: "192.168.33.10"
同じく簡単のためssh configを設定しておきます。
$ vagrant ssh-config --host 192.168.33.10 >> ~/.ssh/config
以下が追記されます。
Host 192.168.33.10 HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/jun06t/vagrant/ubuntu/.vagrant/machines/default/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL
Mac側
デフォルトだとOpenSSHバージョンが8.2未満なのでbrewでインストールします。
$ brew install openssh $ ssh -V OpenSSH_8.8p1, OpenSSL 1.1.1m 14 Dec 2021
Yubikey
Yubikey ManagerであらかじめFIDO2のPINを設定します。
Application→FIDO2を選択

Change PINをクリック。

設定したいPINを入力します。

※初期値は未設定ですが、僕の場合はすでに設定済なのでCurrent PINの入力が求められます
Yubikeyを使ってSSH
鍵の生成
OpenSSH 8.2からはsuffixに-skが付く新しい鍵タイプが用意されています。
- ecdsa-sk
- ed25519-sk
鍵長はどちらも256bitsなので、パフォーマンス上優れているed25519-skの方が良いでしょう。
$ ssh-keygen -t ed25519-sk Generating public/private ed25519-sk key pair. You may need to touch your authenticator to authorize key generation. # FIDO2のPINを入力 Enter PIN for authenticator: # Yubikeyをタッチ You may need to touch your authenticator (again) to authorize key generation. # 変更不要ならEnter Enter file in which to save the key (/Users/jun06t/.ssh/id_ed25519_sk): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /Users/jun06t/.ssh/id_ed25519_sk Your public key has been saved in /Users/jun06t/.ssh/id_ed25519_sk.pub The key fingerprint is: SHA256:imo+msfWx5K2qW1J0pS3GKke0ln1Md8f4GVaX2K6jBU jun06t@Mac The key's randomart image is: +[ED25519-SK 256]-+ | . .+ ...o | | =. oo * + | | + * O + . | | o . = B ...o| | . . S o +.+o+| | + = . oo=*| | o E = .o*| | . . . o . | | . | +----[SHA256]-----+
また-O residentオプションを付けるとYubikeyに秘密鍵を保存してくれます。
$ ssh-keygen -t ed25519-sk -O resident
取り出す時は以下を実行すると
$ ssh-keygen -K # FIDO2 PIN入力 Enter PIN for authenticator: # Yubikeyタッチ You may need to touch your authenticator to authorize key download. # ssh秘密鍵のパスフレーズ(空ならそのままEnter) Enter passphrase (empty for no passphrase): Enter same passphrase again: Saved ED25519-SK key to id_ed25519_sk_rk
カレントフォルダに
- id_ed25519_sk_rk
- id_ed25519_sk_rk.pub
が生成されます。
別のマシンに同じ秘密鍵を置きたい場合に使えそうですね。
一方で紛失した場合のリスクもありますし、後述する課題もあるのでトレードオフを考慮して判断した方がよいです。
公開鍵をサーバ側(Ubuntu)へ登録
公開鍵をコピペしておき
$ cat ~/.ssh/id_ed25519_sk.pub | pbcopy
vagrant ubuntuへログイン後authorized_keyに貼り付けます。
$ vagrant ssh vagrant@ubuntu-focal:~$ vim .ssh/authorized_keys
動作確認
ではsshしてみます。
$ ssh -i ~/.ssh/id_ed25519_sk 192.168.33.10 Confirm user presence for key ED25519-SK SHA256:imo+msfWx5K2qW1J0pS3GKke0ln1Md8f4GVaX2K6jBU User presence confirmed Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-99-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Thu Feb 17 19:02:59 UTC 2022 System load: 0.06 Processes: 115 Usage of /: 4.0% of 38.71GB Users logged in: 0 Memory usage: 20% IPv4 address for enp0s3: 10.0.2.15 Swap usage: 0% IPv4 address for enp0s8: 192.168.33.10 * Super-optimized for small spaces - read how we shrank the memory footprint of MicroK8s to make it the smallest full K8s around. https://ubuntu.com/blog/microk8s-memory-optimisation 20 updates can be applied immediately. 15 of these updates are standard security updates. To see these additional updates run: apt list --upgradable Last login: Thu Feb 17 19:02:54 2022 from 10.0.2.2 vagrant@ubuntu-focal:~$
無事ログインできました。
GitHubのSSHにも対応
で発表されたようにGitHubでgit cloneする時にsshプロトコルを使っている場合はセキュリティキーを使えるようになりました。
公開鍵の登録
SSH and GPG keysでSSH keysに公開鍵を登録します。

動作確認
まずは認証が通るか確認します。
$ ssh -i .ssh/id_ed25519_sk -T git@github.com # Yubikeyタッチ Confirm user presence for key ED25519-SK SHA256:imo+msfWx5K2qW1J0pS3GKke0ln1Md8f4GVaX2K6jBU User presence confirmed Hi jun06t! You've successfully authenticated, but GitHub does not provide shell access.
大丈夫そうです。
git cloneする時はGIT_SSH_COMMANDやcore.sshCommandを使うと良いです。
$ env GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519_sk -F /dev/null" git clone ...
$ git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_sk -F /dev/null" $ git clone ...
その他
-O residentで鍵を生成しなおすと過去の鍵は使えない
単に
$ ssh-keygen -t ed25519-sk
だけであれば過去に同じYubikeyありで発行した秘密鍵は使えますが、一度-O residentをつけると
$ ssh-keygen -t ed25519-sk -O resident
過去に発行した秘密鍵はどれもPermission denied (publickey)で使えなくなりました。
うっかりで過去の鍵が全て使えなくなってしまうとかなり困るので、以下の方針のどちらかに振り切る必要がありそうです。
- 必ずYubikeyに保存した鍵を使う
- 絶対に
-O residentは使わず、都度発行する
スペアキーに秘密鍵を保存することはできない
GPGの時はスペアキーを用意できましたが、U2F/FIDO2対応の秘密鍵はスペアを用意する事はできないようです。
Use same ed25519-sk key with two different Yubikeys : yubikey
- 署名鍵と違って再発行しても問題ない
- 紛失した場合はリスク上鍵を失効すべき
のでスペア管理はしない方が良いですね。