WindowsでYubikey5を使ってみる
前提条件
GPGキーを作成し、Yubikeyに移動させた状態とする。
まだの場合は以下を参照してください。 akashisn.hatenablog.com akashisn.hatenablog.com
環境
- Windows 10 Pro (20H2 - 19042.685)
Gpg4winのインストール
https://files.gpg4win.org/ から最新版をダウンロードする。
Kleopatra
と GpgEX
にチェックを入れてインストールする。
公開鍵のインポート
公開鍵のエクスポート でエクスポートした公開鍵をインポートする。
> gpg --import .\gpg-BF8A708B020A19BB-2020-12-09.txt gpg: 鍵BF8A708B020A19BB: 公開鍵"<名前> <メールアドレス>"をインポートしました gpg: 処理数の合計: 1 gpg: インポート: 1
インポートした公開鍵を究極的に信用する(自分の物のため)。
trust
-> 5
-> y
と入力する。
> gpg --edit-key BF8A708B020A19BB gpg (GnuPG) 2.2.25; Copyright (C) 2020 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. pub nistp521/BF8A708B020A19BB 作成: 2020-12-09 有効期限: 無期限 利用法: C 信用: 不明の 有効性: 不明の sub nistp521/983982062E1BB33D 作成: 2020-12-09 有効期限: 無期限 利用法: S sub nistp521/008734F36B087C1C 作成: 2020-12-09 有効期限: 無期限 利用法: E sub nistp521/26BAE38657860920 作成: 2020-12-09 有効期限: 無期限 利用法: A [ 不明 ] (1). <名前> <メールアドレス> gpg> trust pub nistp521/BF8A708B020A19BB 作成: 2020-12-09 有効期限: 無期限 利用法: C 信用: 不明の 有効性: 不明の sub nistp521/983982062E1BB33D 作成: 2020-12-09 有効期限: 無期限 利用法: S sub nistp521/008734F36B087C1C 作成: 2020-12-09 有効期限: 無期限 利用法: E sub nistp521/26BAE38657860920 作成: 2020-12-09 有効期限: 無期限 利用法: A [ 不明 ] (1). <名前> <メールアドレス> 他のユーザの鍵を正しく検証するために、このユーザの信用度を決めてください (パスポートを見せてもらったり、他から得たフィンガープリントを検査したり、などなど) 1 = 知らない、または何とも言えない 2 = 信用し ない 3 = まぁまぁ信用する 4 = 充分に信用する 5 = 究極的に信用する m = メーン・メニューに戻る あなたの決定は? 5 本当にこの鍵を究極的に信用しますか? (y/N) y pub nistp521/BF8A708B020A19BB 作成: 2020-12-09 有効期限: 無期限 利用法: C 信用: 究極 有効性: 不明の sub nistp521/983982062E1BB33D 作成: 2020-12-09 有効期限: 無期限 利用法: S sub nistp521/008734F36B087C1C 作成: 2020-12-09 有効期限: 無期限 利用法: E sub nistp521/26BAE38657860920 作成: 2020-12-09 有効期限: 無期限 利用法: A [ 不明 ] (1). <名前> <メールアドレス> プログラムを再起動するまで、表示された鍵の有効性は正しくないかもしれない、 ということを念頭においてください。 gpg> q
SSHキーとして使う
GPGの認証SubキーをSSHキーの代わりに使うことができる。 そのため、今まで複数の鍵を管理していたのをYubikeyにある取り出せない秘密鍵に集約することが出来るため利便性も向上しセキュリティ的にも良い感じになる。
scdaemonの設定
Windows10には既に仮想スマートカードリーダ(Windows Helloなど)がインストールされているため、scdaemonがちゃんとYubikeyを使用するようにする必要がある。
Yubikeyがささった状態で以下でデバイスを取得することが出来るので、 デバイス名を%APPDATA%\gnupg\scdaemon.conf
に設定してあげる。
> Get-PnpDevice -Class SoftwareDevice | Where-Object {$_.FriendlyName -like "*YubiKey*"} | Select-Object -ExpandProperty FriendlyName Yubico YubiKey OTP+FIDO+CCID 0
reader-port Yubico YubiKey OTP+FIDO+CCID 0
gpg-agentの設定
gpg-agentはssh-agentとしても動作することが出来るので、
%APPDATA%\gnupg\gpg-agent.conf
に設定する。
enable-ssh-support enable-putty-support
設定を適応するためにagentを再起動する
> gpg-connect-agent killagent /bye OK closing connection > gpg-connect-agent /bye gpg-connect-agent: gpg-agentが実行されていません - 'C:\Program Files (x86)\GnuPG\bin\gpg-agent.exe'を開始します gpg-connect-agent: agent の起動のため、5秒待ちます... gpg-connect-agent: agent への接続が確立しました。
認識しているかを確認する。
> gpg --card-status Reader ...........: Yubico YubiKey OTP FIDO CCID 0 Application ID ...: Dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Yubico Serial number ....: xxxxxxxx Name of cardholder: <名><姓> Language prefs ...: ja Salutation .......: URL of public key : Login data .......: <Email等> Signature PIN ....: 強制なし Key attributes ...: nistp521 nistp521 nistp521 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 9 KDF setting ......: off Signature key ....: xxxx xxxx xxxx xxxx xxxx xxxx xxxx created ....: 2020-12-09 14:35:35 Encryption key....: xxxx xxxx xxxx xxxx xxxx xxxx xxxx created ....: 2020-12-09 14:36:18 Authentication key: xxxx xxxx xxxx xxxx xxxx xxxx xxxx created ....: 2020-12-09 14:37:21 General key info..: sub nistp521/983982062E1BB33D 2020-12-09 <名前> <メールアドレス> sec# nistp521/BF8A708B020A19BB 作成: 2020-12-09 有効期限: 無期限 ssb> nistp521/983982062E1BB33D 作成: 2020-12-09 有効期限: 無期限 カード番号: 0006 xxxxxxxxx ssb> nistp521/008734F36B087C1C 作成: 2020-12-09 有効期限: 無期限 カード番号: 0006 xxxxxxxxx ssb> nistp521/26BAE38657860920 作成: 2020-12-09 有効期限: 無期限 カード番号: 0006 xxxxxxxxx
SSH形式の公開鍵に変換する
> gpg --export-ssh-key BF8A708B020A19BB > ~/.ssh/gpg-BF8A708B020A19BB.pub
作成した公開鍵は普通のSSHの公開鍵と同じように扱う。
つまり、接続先の~/.ssh/authorized_keys
に追記する。
agent socketのproxyを行う
Windows 10にネイティブにあるOpenSSHではGnuPGが出力するsocketをうまく扱えないようなので、 github.com
socketファイルをWindowsの名前付きパイプにプロキシしてくれるプログラムを使用する。
最新版の wsl2-gpg-agent.exe
を適当なところ(今回は C:\tools\utils\wsl2-gpg-agent\wsl2-gpg-agent.exe
においた) にコピーする。
> wsl2-gpg-agent.exe --winssh ssh-pageant
と実行するとpageantを\\.\pipe\ssh-pageant
にプロキシした状態でシステムトレイに常駐するようになる。
この状態で、SSH_AUTH_SOCK=\\.\pipe\ssh-pageant
という環境変数をセットすることによりsshクライアントはプロキシされたgpg-agentを参照するようになる
接続テストをするために既存の ~/.ssh/config
での設定をコメントアウトしておく。
> ssh git@github.com PTY allocation request failed on channel 0 Hi AkashiSN! You've successfully authenticated, but GitHub does not provide shell access. Connection to github.com closed.
github.comにsshをすると、このようにPINを聞かれてちゃんと接続できることが確認できる。
設定の永続化
自動起動の設定
$UserProperty = $(Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders') $WsShell = New-Object -ComObject WScript.Shell $Shortcut = $WsShell.CreateShortcut($UserProperty.Startup+"\wsl2-gpg-agent.exe.lnk") $Shortcut.TargetPath = "C:\tools\utils\wsl2-gpg-agent\wsl2-gpg-agent.exe" $Shortcut.Arguments = "--winssh ssh-pageant" $Shortcut.WorkingDirectory = "C:\tools\utils\wsl2-gpg-agent" $Shortcut.IconLocation = "C:\tools\utils\wsl2-gpg-agent\wsl2-gpg-agent.exe" $Shortcut.Save()
環境変数の設定
環境変数も設定しておく
SSH_AUTH_SOCK=\\.\pipe\ssh-pageant
SSHの設定
~/.ssh/config
で何か設定するときは、
Host github.com
HostName github.com
IdentityFile ~/.ssh/gpg-BF8A708B020A19BB.pub
IdentitiesOnly yes
このように、IdentityFile
に先ほど作成した公開鍵を設定すると良い。
Git for Windowsの設定
Git for Windowsにはsshコマンドが付属しているため、WindowsネイティブのSSHを使うように設定しないとうまく動かない。
> git config --global core.sshCommand 'C:/Windows/System32/OpenSSH/ssh.exe'
GitHubでのコミット署名
gpg-BF8A708B020A19BB-2020-12-09.txt
の公開鍵を https://github.com/settings/keys に設定する。
Gitの設定を行う。
> git config --global user.signingkey BF8A708B020A19BB > git config --global gpg.program 'C:/Program Files (x86)/gnupg/bin/gpg.exe'
デフォルトで署名するには以下を実行する。
> git config --global commit.gpgsign true
手動でコミットに署名をするときは -S
オプションを加える。
$ git commit -S -m your commit message
このときOpenPGPのPINを求められる。
ちゃんと署名できていればこんな感じにVerifyマークがつく
WSL2で使う
WSL2ではUSBシリアルをサポートしていないため直接Yubikeyに接続することは出来ない。
そこで、Windowsの名前付きパイプをUnixソケットへプロキシしてAgent転送を行うことでWSL2でもYubikeyを使うことが出来る。
先ほどの wsl2-gpg-agent.exe
を使う。
公開鍵のインポート
Windowsで行ったのと同様に公開鍵をインポートして、信用しておく。
WSL2側の設定
socat, lsof のインストールをする
$ sudo apt update $ sudo apt install socat iproute2
.zshrc
に以下を追加してログイン時に起動するようにする
wsl2_ssh_pageant_bin="/mnt/c/tools/wsl2-ssh-pageant/wsl2-ssh-pageant.exe" if test -x "$wsl2_ssh_pageant_bin"; then export SSH_AUTH_SOCK="$HOME/.gnupg/S.gpg-agent.ssh" if ! ss -a | grep -q "$SSH_AUTH_SOCK"; then rm -f "$SSH_AUTH_SOCK" (setsid nohup socat UNIX-LISTEN:"$SSH_AUTH_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin --ssh" >/dev/null 2>&1 &) fi export GPG_AGENT_SOCK="$HOME/.gnupg/S.gpg-agent" if ! ss -a | grep -q "$GPG_AGENT_SOCK"; then rm -rf "$GPG_AGENT_SOCK" (setsid nohup socat UNIX-LISTEN:"$GPG_AGENT_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin --gpg S.gpg-agent" >/dev/null 2>&1 &) fi export GPG_AGENT_EXTRA_SOCK="$HOME/.gnupg/S.gpg-agent.extra" if ! ss -a | grep -q "$GPG_AGENT_EXTRA_SOCK"; then rm -rf "$GPG_AGENT_EXTRA_SOCK" (setsid nohup socat UNIX-LISTEN:"$GPG_AGENT_EXTRA_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin --gpg S.gpg-agent.extra" >/dev/null 2>&1 &) fi else echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable." fi unset wsl2_ssh_pageant_bin
再度ログインしてYubikeyが認識しているかを確認する。
$ gpg --card-status Reader ...........: Yubico YubiKey OTP FIDO CCID 0 Application ID ...: Dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Yubico Serial number ....: xxxxxxxx Name of cardholder: <名><姓> Language prefs ...: ja Salutation .......: URL of public key : Login data .......: <Email等> Signature PIN ....: 強制なし Key attributes ...: nistp521 nistp521 nistp521 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 9 KDF setting ......: off Signature key ....: xxxx xxxx xxxx xxxx xxxx xxxx xxxx created ....: 2020-12-09 14:35:35 Encryption key....: xxxx xxxx xxxx xxxx xxxx xxxx xxxx created ....: 2020-12-09 14:36:18 Authentication key: xxxx xxxx xxxx xxxx xxxx xxxx xxxx created ....: 2020-12-09 14:37:21 General key info..: sub nistp521/983982062E1BB33D 2020-12-09 <名前> <メールアドレス> sec# nistp521/BF8A708B020A19BB 作成: 2020-12-09 有効期限: 無期限 ssb> nistp521/983982062E1BB33D 作成: 2020-12-09 有効期限: 無期限 カード番号: 0006 xxxxxxxxx ssb> nistp521/008734F36B087C1C 作成: 2020-12-09 有効期限: 無期限 カード番号: 0006 xxxxxxxxx ssb> nistp521/26BAE38657860920 作成: 2020-12-09 有効期限: 無期限 カード番号: 0006 xxxxxxxxx
これでWSL2でも使用することができたので後は普通のLinuxと同様にコミット署名とかを設定する。
トラブルシューティング
WSL2でいきなり動かなくなったら、
> wsl --shutdown
でwslの再起動を行えばたいてい治る