Yubikeyでsshする一番簡単かつ確実な方法
#yubikey #linux #ssh
Wrote: 2025/5/4
FIDO2機能を使いましょう。条件が揃っていれば一瞬です
なんか間違ってたら教えてください
FIDO2を使う利点
標準化されておりどのOSでも共通
特殊なツールは不要で、標準的なOpenSSHのツールチェインで対応できる
例えばGPGの場合はgpgコマンドを使う必要があった
gpg-agent地獄から解放されます
UPを要求できる
User Presence
「実際にユーザがそのYubikeyをタッチする」ことを要求できる
UVを要求できる
User Verification
PINを入力したり、指紋認証(Yubikeyが対応している場合)を要求できる
Prerequisites
OpenSSH 8.3+
8.2からFIDO2サポートが入ったため https://www.openssh.com/txt/release-8.2
ただし、Yubikeyのドキュメントによれば8.3以降とされている(バグフィックスとかだと思う)
sshする双方のマシンで必要
現代のマシンなら9以降になっているはず
FIDO2に対応したYubikey(FIDO2に対応していればどのトークンでもよい)
Yubikeyの場合5以降
最新のSecurity Key SeriesもFIDO2に対応している
Yubikey 5シリーズは最大で25個のFIDO2 Discoverable Credentialを格納できる
https://docs.yubico.com/hardware/yubikey/yk-tech-manual/yk5-apps.html#fido2
25個のホストまででしか使えないという意味ではない。鍵を使い回さなければ25個ということ
windymelt.icon ここから買うと俺が儲かるぞ。
https://amzn.to/434Y6DW
登場人物
クライアント
あなたのマシンのこと
relying party(RP)
クライアントを認証したいサービスのこと
ここではどこかのSSHサーバのこと
マスターキー
Yubikey内部で自動生成され、Yubikeyごとにユニークであり、Yubikey外部に絶対に露出しない鍵
鍵ペア
これを利用して認証を実施する。
ssh-keygenで「作って〜」とYubikeyにお願いできる
ふつうのssh鍵の場合は・・・
opensshにより秘密鍵と公開鍵とのペアがディスク上に生成され、秘密鍵は大事にして、公開鍵は相手に渡していい
FIDO2の場合・・・
Yubikeyが秘密鍵と公開鍵とのペアを生成する
秘密鍵はクライアントに露出させない。秘密鍵をさらにマスターキーで暗号化し、いろいろなメタデータをつけてクライアントに返す → 鍵ハンドル
公開鍵はそのまま返す
鍵ハンドル
鍵ペア+メタデータをYubikeyのマスターキーで暗号化したもの
当然、クライアント単体だと何もできない
鍵ハンドル・Yubikey・サーバに預けた公開鍵の三位一体で動作する
RPはクライアントにチャレンジを送る
クライアントはYubikeyに鍵ハンドルとチャレンジを送る
Yubikeyはマスターキーで鍵ハンドルを開錠し、取り出した秘密鍵でチャレンジに署名し、クライアントに返す
クライアントは署名をRPに渡す
RPは署名を検証し、認証成功
重要ポイント
鍵ハンドルはクライアントが持っててもいいし、RPが持っていてもいいし、Yubikeyに突っ込んでもいい
秘密鍵を取り出せるのはYubikeyだけだから
クライアントが持つ
鍵ハンドルを持っているクライアントのみがsshできるようになる
普通にクライアントごとにSSH秘密鍵を生成するのとあまり変わらないパターン
RPが持つ
SSHに限らず、ただの二要素認証として使う場合はこれ
クライアントにかかわらず、同じYubikeyさえ持っていれば認証できる
鍵自体は暗号化されてるので問題ない
SSHだと公開鍵を別途サーバに渡してあるのでやる意味がないのだが、Webサイトの二要素認証だと鍵ハンドルをRPが持っていないと認証できない
これはFIDOでU2Fとして使われていたパターン
FIDO 2ではCTAP 1と呼ばれている
Yubikeyに突っ込む
今回はこれを使う
これ以外のパターンでは実はYubikeyのストレージを消費しない
鍵は鍵ハンドルとして外部から与えられる
マスターキーは最初からあるのを使うだけでいい
秘密鍵は動的に展開され、署名が終わったら棄てる
鍵ハンドルをYubikeyに保存する場合はそのぶんストレージを消費するので個数制限がある
Yubikey 5だと25個
同じ鍵を使い回せばいいのでサーバ数に制限はない
Yubikeyさえあれば秘密鍵を使って署名できるようになる
どのクライアントでも使えるし、同じYubikeyを複数のサーバで使い回せる
CTAP 2で実現
手順(初回の鍵作成)
Yubikeyをホストに挿入する
ssh-keygen経由でFIDO2を利用してYubikey内に鍵を作成する
ssh-keygen -t ed25519-sk -O resident -O verify-required -C "コメント"
ただし、
-t ed25519-skはed25519鍵ペアをsk、すなわちSecurity Keyに作成するという指定
今のところ他にもecdsa-skが存在する。大差ないのでed25519-dkでよいと思う
-O residentはYubikey内に鍵ハンドルを保管するオプション。入れておくとYubikeyを他のサーバやクライアントでも使い回せるようになる
resident credentialと呼ばれていた名残りでこのように書かれているが、今はDiscoverable Credentialと呼ばれているようだ
-O verify-required は鍵を利用する際にYubikeyの認証を要求するオプション。具体的にはPINを要求される。
ちなみに-O no-touch-requiredを追加でつけるとタッチしなくてよくなるが、セキュリティと相談になる
-C "コメント"は同じYubikeyに保管された他の鍵と識別するためのコメント。
パスワードを要求されるが空にするか指定するかはどちらでもいい
パスワードを指定するとパスワードとYubikeyのPINとが必要になる
パスワードを空にすればPINだけでいい
PINを要求されるのでこの鍵ペアのためにPINを入れる
たぶんYubikeyで共通ではなく、鍵ペア単位で決められるはず(自信なし)
するとid_ed25519_sk_rkが作成される
これが鍵ハンドルと呼ばれるもの。秘密鍵そのものではない。秘密鍵を生成するのに必要な情報、くらいの意味
id_ed25519_sk_rk.pubも生成される
これはただの公開鍵
手順(サーバごと)
.ssh/id_ed25519_sk_rk.pubを接続先のサーバに登録する
手順(クライアントごと)
1. 鍵ハンドルを取り出す(鍵を生成したホストでは既に鍵ハンドルがあるのでスキップ)
-O residentを使っているので、鍵ハンドル取り出しはssh-keygen -Kやssh-add -Kで可能
-K Download resident keys from a FIDO authenticator. Public and private key files will be written to the current directory for each downloaded key. If multiple FIDO authenticators are attached, keys will be downloaded from the first touched authenticator. See the “FIDO AUTHENTICATOR” section for more information.
ssh-add -Kする場合
たぶんこっちが便利
ssh agentに登録される。ファイルには保存されないのでエージェントが再起動したらその都度実行する
ssh-add -Lしたら登録されたかどうか確認できる
ssh-keygen -Kする場合
ファイルとして保存される
なぜかpwdに作成されるので~/.ssh/にmvすること
2. (ssh-keygen -Kする場合)
sshはどうやら自動的にFIDO2トークンを利用してくれない?ようなので.ssh/configを設定する
code:ssh
Host xxx.yyy.zzz.aaa
IdentityFile ~/.ssh/id_ed25519_sk_rk
あとはsshするだけ
参考文献
WebauthnのResident Keyについて(+Passkeyについて) #WebAuthn - Qiita
The complete guide to SSH with FIDO2 security keys | by Jonas Markström | Medium
SSH Resident Key Guide