Carpe Diem

備忘録

SSHにYubikeyを使う

背景

OpenSSH 8.2からU2F/FIDO2デバイスを用いたハードウェア認証に対応しており、仮に秘密鍵が漏洩しても鍵の生成時に利用したデバイス(Yubikeyなど)がないとsshできなくなるというセキュアな対応が実現できます。

以前はOpenPGPに委譲させたり、PIVで対応するといった選択肢がありましたが、それぞれ設定がやや大変だったのでこの対応は非常に嬉しいです。

環境

  • ローカルMac
    • OpenSSH 8.8p1
  • Ubuntu 20.04
    • OpenSSH 8.2p1

OpenSSH 8.2以上のサーバー・クライアントが必要です。

事前準備

Ubuntu

VagrantUbuntu環境を用意しておきます。

$ 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を選択

f:id:quoll00:20220218032920p:plain

Change PINをクリック。

f:id:quoll00:20220218033249p:plain

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

f:id:quoll00:20220218033112p:plain

※初期値は未設定ですが、僕の場合はすでに設定済なので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:~$

無事ログインできました。

GitHubSSHにも対応

www.yubico.com

で発表されたようにGitHubでgit cloneする時にsshプロトコルを使っている場合はセキュリティキーを使えるようになりました。

公開鍵の登録

SSH and GPG keysSSH keysに公開鍵を登録します。

f:id:quoll00:20220218042653p:plain

動作確認

まずは認証が通るか確認します。

$ 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_COMMANDcore.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

  • 署名鍵と違って再発行しても問題ない
  • 紛失した場合はリスク上鍵を失効すべき

のでスペア管理はしない方が良いですね。

参考