[PR]
あまねけ!の更新を見逃したくない方にはフィードの購読がおすすめです。お好みのフィードリーダーであまねけ!の新着記事をお楽しみください。
status.amane.moeでは、各サービスの運用状況をお知らせしています。アクセスできなかったり動作が不安定な場合はこちらをご確認ください。
ご意見・ご感想がありましたら、ぜひコメントフォームからお送りください。記事最下部の「返信」ボタンもお使いいただけます。

WSL2でYubikeyを使う

/* この記事は、WSLでYubikeyを使うの情報をWSL2向けに書き直したものです。詳細については元の記事もお読みください。 */

概要

WSLからYubikeyを使う方法について、WSL→WSLのGnuPG→socat→npiperelay→Windowsのgpg-agent→scdaemon→Yubikey、またはssh→ssh-agent→wsl-ssh-pagent→Windowsのgpg-agent→scdaemon→Yubikeyという流れで接続できることを示す図(記事では触れないが、RemoteFXを通すとリモートデスクトップの接続先からでもYubiKeyを使用できることを提示)

前提

Yubikey

今回はPIVではなく、OpenPGPコンパチブルなスマートカードとして使用します。鍵のセットアップは各自で済ませてください。

WSL

WSL2を使います。systemdを有効にしておくことをおすすめします。

準備

gpg

Yubikeyをgpg-agent経由で引き渡す必要があるので、両方にインストールしてください。

on WSL

amane@yakumo:~$ sudo apt update && sudo apt install -y gpg
amane@yakumo:~$ gpg --version
gpg (GnuPG) 2.2.40

on Windows

Gpg4winをインストールします。選択可能なコンポーネントは入れても入れなくてもいいです。

WindowsでYubikeyが認識できることを確認してください。Windowsで認識できなければWSLでも参照できません。

C:\Users\amane>gpgconf --reload scdaemon

C:\Users\amane>gpg --card-status
Reader ...........: Yubico YubiKey OTP FIDO CCID 0
Application ID ...: ********************************
Application type .: OpenPGP
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: ********************************
Name of cardholder: Amane Katagiri
Language prefs ...: ja
Salutation .......: Ms.
URL of public key : https://keybase.io/amane/pgp_keys.asc
Login data .......: amane
Signature PIN ....: 強制
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: **** **** **** **** ****  **** **** **** **** ****
      created ....: 1970-01-01 00:00:00
Encryption key....: **** **** **** **** ****  **** **** **** **** ****
      created ....: 1970-01-01 00:00:00
Authentication key: **** **** **** **** ****  **** **** **** **** ****
      created ....: 1970-01-01 00:00:00
General key info..: [none]

上手くいかない場合は、 %APPDATA%\gnupg\scdaemon.conf に以下を追記してやり直してください:

reader-port Yubico

後で使うので%APPDATA%\gnupg\gpg-agent.confに追記してください:

enable-ssh-support
enable-putty-support

npiperelay

npiperelay is a tool that allows you to access a Windows named pipe in a way that is more compatible with a variety of command-line tools.
NZSmartie/npiperelay

Windowsの名前付きパイプをよしなにUNIXソケットにリレーする。GnuPGが使うlibassuan向けのサポートつき。

npiperelay.exe%HOMEDRIVE%%HOMEPATH%\go\binあたりに置いてください。

wsl2-ssh-pageant

I use a Yubikey to store a GPG key pair and I like to use this key pair as my SSH key too. GPG on Windows exposes a Pageant style SSH agent and I wanted a way to use this key within WSL2.
BlackReloaded/wsl2-ssh-pageant

PageantをよしなにUNIXソケットにリレーする。どうしてもgpg-agent経由でsshできなかったので入れました。WSL2では元記事に記載のwsl-ssh-pageantが使えなくなっていたのでこちらを使います。

wsl2-ssh-pageant.exe%HOMEDRIVE%%HOMEPATH%\go\binあたりに置いてください。

socat

Multipurpose relay (SOcket CAT)
socat(1)

npipereleyでよしなにしたgpg-agentのソケットを、WSL側のgpg-agentのソケットにつなぐ。

WSLでインストールしてください:

amane@yakumo:~$ sudo apt update && sudo apt install -y socat
amane@yakumo:~$ socat -V
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
socat version 1.7.3.2 on Nov 19 2017 13:56:10

起動

on Windows

適当にバッチファイルとして置いてください:

gpg-connect-agent reloadagent /bye > nul 2>&1

タスクスケジューラからVBScript経由で呼び出すと かわいい かもしれないです:

Set ws = CreateObject("Wscript.Shell")
ws.run "cmd /c C:\path\to\start-agent.bat", vbhide

on WSL2

.bashrcなどに追記してください:

WIN_USERNAME="amane"

GO_BIN_DIR="/mnt/c/Users/${WIN_USERNAME}/go/bin"
WIN_GPG_DIR="C:/Users/${WIN_USERNAME}/AppData/Local/gnupg"
WIN_HOME_DIR="/mnt/c/Users/${WIN_USERNAME}"
WSL_GPG_DIR="$(gpgconf --list-dirs socketdir)"

if ! pgrep -f 'socat.*gpg-agent.*npiperelay' >/dev/null; then
  rm -f "${WSL_GPG_DIR}/S.gpg-agent"
  setsid nohup socat \
    UNIX-LISTEN:"${WSL_GPG_DIR}/S.gpg-agent,fork" \
    EXEC:"${GO_BIN_DIR}"'/npiperelay.exe -ei -ep -s -a "'"${WIN_GPG_DIR}"'/S.gpg-agent",nofork' >/dev/null 2>&1 &
fi
export SSH_AUTH_SOCK="/tmp/wsl2-ssh-pagent.sock"
if ! pgrep -f 'socat.*wsl2-ssh-pagent.*' >/dev/null; then
  rm -f "${SSH_AUTH_SOCK}"
  setsid nohup socat \
    UNIX-LISTEN:"${SSH_AUTH_SOCK},fork" \
    EXEC:"${GO_BIN_DIR}"'/wsl2-ssh-pageant.exe' >/dev/null 2>&1 &
fi

PIDとかを記録すれば、もっと丁寧に二重起動を回避できますね。

なお、ここまで実施しても動作しない場合、gpg-agent.socketとsocatが競合しているかもしれません。当該のsystemdサービスを停止してください。

systemctl disable --global gpg-agent.socket

おしらせ

今後のWSLのアップデートで記載している手順が動作しなくなった場合は、気付き次第この記事を修正する予定です(WSL3がリリースされた場合はまた別の記事に分割すると思います)。

参考

「読んだ」を押すと、あなたがボタンを押した事実を明示的に通知してこのページに戻ります。このページに戻ってからブラウザの「戻る」ボタンを押すと、何度か同じページが表示されることがあります。