🗂

FIDO2 デバイスと SSH 鍵

2023/06/29に公開

FIDO2 デバイスと SSH 鍵

Yubico さんの情報によると、OpenSSH 8.2p1 で OpenSSH に FIDO2 を利用した鍵管理ができるようになりました。

Starting with 8.2p1, OpenSSH has added support for registering and authenticating with FIDO2 Credentials.

SSH は公開鍵認証をサポートしています。パソコン側に秘密鍵を保存するのですが、その名の通り誰にも渡してはいけません。しかし、パソコンにファイルとしてある以上、漏洩しないとは限りません。漏洩しても即悪用されないようにパスフレーズでさらに鍵をかけるのですが、このパスフレーズもそれなりの強度にしなければなりません。覚えるのが大変です。

FIDO2 に対応したということは、この秘密鍵の管理を FIDO2 デバイスが行い、認証器で認証されない限り秘密鍵を利用できないということです。TPM やセキュリティキーを利用しますので、何もしていないのに秘密鍵が漏洩することはまず考えられません。

FIDO2 認証器が使えるので、PIN や指紋やセキュリティキーなどが利用できます。長く覚えにくいパスフレーズを使わないで済みます。

Windows の場合

Windows 11 は標準で OpenSSH がインストールされていますが、FIDO2 には対応していません。GitHub で開発されている、PowerShell/Win32-OpenSSH を使う必要があります。

> winget install Microsoft.OpenSSH.Beta

とします。ターミナルを再起動すれば、使えるようになります。

> ssh -V
OpenSSH_for_Windows_9.2p1, LibreSSL 3.7.2

SSH 鍵の作成と利用

FIDO2 対応のアルゴリズムは ecdsa-sked25519-sk の二つです。ssh-keygen でアルゴリズムを指定します。

> ssh-keygen -t ecdsa-sk

なお、ed25519-sk は Windows Hello では使えないようです。なぜかはわからないのですが、自分の環境だと ecdsa-sk は Windows Hello と Yubikey の両方が使えましたが、ed25519-sk は Yubikey のみしか使えませんでした。

.ssh/id_ecdsa_sk.pub に公開鍵が、.ssh/id_ecdsa_sk に秘密鍵を FIDO2 デバイスで暗号化したもの (多分) が格納されています。

後はいつものように、公開鍵をサーバーの .ssh/authorized_keys に配置したうえで、slogin your.server.example でログインするだけです。Windows Hello であれば PIN や指紋認証などで、セキュリティキーであればタッチをすればログインできます。

セキュリティキー用の SSH 鍵のカスタマイズ

アルゴリズムのほかにフラグを指定できます。FIDO2 関係のものをいくつか紹介します。

  • resident - SSH 鍵を認証器に保存します。別のパソコンにセキュリティキーを挿して利用でき、パソコンごとに SSH 鍵を作成する必要がなくなります。
  • verify-required - ユーザー認証を必須にします。Yubikey では PIN を要求されます。
  • no-touch-required - セキュリティキーのタッチを不要にします。

resident

標準では SSH の秘密鍵は FIDO2 デバイスで暗号化されたうえでパソコンにファイルとして保存されます。(多分) 基本的に、パソコンごとに SSH 鍵を生成することには変わりはありません。

ssh-keygen -t ecdsa-sk -O resident と指定すると、SSH 鍵は FIDO2 デバイスにも保存され、他のパソコンでも利用することができます。ssh-keygen -k コマンドの実行で FIDO2 デバイスに保存されている SSH 鍵をエクスポートできます。(Windows では管理者モードで実行してください)

なお、SSH 鍵のエクスポート時は PIN が要求されます。セキュリティキーを紛失したら即 SSH 鍵を奪われるわけではありません。

verify-required

標準では SSH 鍵を利用するのに、セキュリティキーのタッチを要求されます。これによって所有証明になります。

ssh-keygen -t ecdsa-sk -O verify-required とすることで、PIN による知識認証が必要になり、二要素認証となります。

サーバー側の .ssh/authorized_keys に次のようにすることで、クライアントに二要素認証を強制できます。

# https://manpages.debian.org/unstable/openssh-server/authorized_keys.5.en.html#verify-required より抜粋

# Require user-verification (e.g. PIN or biometric) for FIDO key
verify-required sk-ecdsa-sha2-nistp256@openssh.com ...

なお、Windows Hello では、このフラグのありなしにかかわらず、PIN (ないしは顔認証など) が要求されます。

no-touch-required

ssh-keygen -t ecdsa-sk -O no-touch-required とすることで、SSH 鍵を利用するのに、セキュリティキーのタッチを不要にします。

タッチも PIN も不要ですので、マルウェアが SSH 鍵を悪用するかもしれません。タッチもしくは PIN があった方が無難です。

ただし、ControlMaster によるコネクションの共有や、ssh-agent によるエージェントの利用でも同様にマルウェアに悪用される危険性はあります。no-touch-required だけが危険なわけではありません。

不明点

手持ちの Windows 11 のパソコンで、Windows Hello による ecdsa-sk SSH 鍵の作成に失敗するパソコンとそうでないパソコンがあります。

自分の手元だと、仮想マシン上の Windows 11 (TPM は有効にしている) では十中八九失敗しました。

おまけ

Yubikey に登録した resident な SSH 鍵を削除する

Yubikey Manager CLI を使います。(Windows では管理者モードで起動したターミナルで実行してください)

まずは、Yubikey を USB に挿した上で、クレデンシャルのリストを表示します。

$ ykman fido credentials list
Enter your PIN:
ssh: 45... openssh
ssh: e7... openssh
webauthn.io ... unknown

SSH 鍵だけでなく、WebAuthn 用のクレデンシャルなども表示されます。

削除したいクレデンシャルの ID を指定して削除します。

$ ykman fido credentials delete 45...
Enter your PIN:
Delete credential ssh 45... openssh? [y/N]: y

最後に

Windows Hello や Touch ID などの標準の FIDO2 デバイスを利用すれば、SSH 鍵の長ったらしいパスフレーズを覚えなくてもよくなります。そのうえ、漏洩にも強くなります。

セキュリティキーを使えば持ち運ぶこともできます。

使わない手はないですよね!

Discussion