This section is useful for establishing a baseline and for solving the Workaround: Too Many Authentication Failures problem. Otherwise, this section is optional.
-
Install OpenSC (win64)
-
Test smart card access
In PowerShell& 'C:\Program Files\OpenSC Project\OpenSC\tools\pkcs11-tool.exe' --login --test
-
SSH into host
In PowerShellssh -I 'C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll' user@host
-
Download and install rfdonnelly/WinCryptSSHAgent
NoteThis is a fork of buptczq/WinCryptSSHAgent which makes makes the following workarounds unnecessary: Workaround: Too Many Authentication Failures, Workaround: Compile WinCryptSSHAgent from Source. -
Run WinCryptSSHAgent
In PowerShell.\WinCryptSSHAgent.exe --smart-card-logon-only
-
Expose to WSL 2
-
Right click on the WinCryptSSHAgent icon in the Windows system tray
-
Select "Show WSL2 / Linux on Hyper-V Settings"
This will install the WinCryptSSHAgent Hyper-V service and may require a restart.
-
Install socat
In WSL 2sudo apt install socat
-
Create the WinCryptSSHAgent socket
In WSL 2export WINCRYPT_SSH_AUTH_SOCK=/tmp/wincrypt-hv.sock already_running=$(ss -lnx | grep -q $WINCRYPT_SSH_AUTH_SOCK; echo $?) if test $already_running != 0; then rm -f $WINCRYPT_SSH_AUTH_SOCK echo "[WinCrypt SSH Agent] Starting relay" (setsid nohup socat UNIX-LISTEN:$WINCRYPT_SSH_AUTH_SOCK,fork SOCKET-CONNECT:40:0:x0000x33332222x02000000x00000000 >/dev/null 2>&1 &) else echo "[WinCrypt SSH Agent] Using existing relay" fi
NoteThis is similar to what the WinCryptSSHAgent "WSL2 / Linux on Hyper-V Settings" provide but with the following major differences:
-
SSH_AUTH_SOCK
environment variable renamed toWINCRYPT_SSH_AUTH_SOCK
so that it can coexist with another SSH Agent -
Run
socat
in the background -
Add
echo
statements
NoteThis snippet can be added to your shell rc to automate it.
-
-
-
List available keys
In WSL 2SSH_AUTH_SOCK=$WINCRYPT_SSH_AUTH_SOCK ssh-add -l
-
SSH into host
In WSL 2SSH_AUTH_SOCK=$WINCRYPT_SSH_AUTH_SOCK ssh user@host
ImportantIf too many keys are provided, SSH will fail to authenticate since the SSH server will only allow the client to try a limited number of keys before disconnecting. You will get an error like:
Received disconnect from x.x.x.x port 22:2: Too many authentication failures
If this happens, see Workaround: Too Many Authentication Failures.
-
Add to
~/.ssh/config
~/.ssh/config
Host <host> User <user> IdentityAgent $WINCRYPT_SSH_AUTH_SOCK
-
SSH into host using SSH config
In WSL 2ssh host
If WinCryptSSHAgent provides too many keys, you will need to tell SSH which key to use via an IdentityFile.
-
Determine which key is the right one
In PowerShellssh -I 'C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll' user@host -v
Note the fingerprint of the key that was used.
-
Find the same fingerprint provided by WinCryptSSHAgent
In WSL 2SSH_AUTH_SOCK=$WINCRYPT_SSH_AUTH_SOCK ssh-add -l
Note the line number.
-
Isolate the fingerprint
In WSL 2SSH_AUTH_SOCK=$WINCRYPT_SSH_AUTH_SOCK ssh-add -l | head -n$line | tail -n1
Adjust
$line
until the correct fingerprint is returned. -
Copy the key to an IdentifyFile
In WSL 2SSH_AUTH_SOCK=$WINCRYPT_SSH_AUTH_SOCK ssh-add -L | head -n$line | tail -n1 > ~/.ssh/id.pub
-
SSH into host
In WSL 2SSH_AUTH_SOCK=$WINCRYPT_SSH_AUTH_SOCK ssh user@host -i ~/.ssh/id.pub
-
Add to
~/.ssh/config
~/.ssh/config
Host <host> User <user> IdentityAgent $WINCRYPT_SSH_AUTH_SOCK IdentityFile ~/.ssh/id.pub
-
SSH into host using SSH config
In WSL 2ssh host
-
Install Go for Windows
-
Install build script dependency
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo
-
Clone WinCryptSSHAgent
git clone https://github.com/buptczq/WinCryptSSHAgent.git cd WinCryptSSHAgent
-
Apply the following diff
This avoids conflict with other SSH Agents like the Windows SSH Agent and the 1Password SSH Agent.
diff --git a/app/app.go b/app/app.go index a780eb2..bd13005 100644 --- a/app/app.go +++ b/app/app.go @@ -8,7 +8,7 @@ import ( const ( WSL_SOCK = "wincrypt-wsl.sock" CYGWIN_SOCK = "wincrypt-cygwin.sock" - NAMED_PIPE = "\\\\.\\pipe\\openssh-ssh-agent" + NAMED_PIPE = "\\\\.\\pipe\\wincrypt-ssh-agent" APP_CYGWIN = iota APP_WSL APP_WINSSH
-
Build WinCryptSSHAgent
.\build.bat
> systeminfo | findstr /B /C:"OS Name" /B /C:"OS Version" OS Name: Microsoft Windows 11 Pro OS Version: 10.0.22631 N/A Build 22631 > ssh -V OpenSSH_for_Windows_8.6p1, LibreSSL 3.4.3 > & 'C:\Program Files\OpenSC Project\OpenSC\tools\opensc-tool.exe' --version OpenSC-0.24.0, rev: f15d0c52, commit-time: 2023-12-13 10:43:57 +0100 > go version go version go1.22.0 windows/amd64
> lsb_release -a | grep Description Description: Ubuntu 23.04 > uname -a Linux hyperion 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux > socat -V | grep 'socat version' socat version 1.7.4.4 on 06 Nov 2022 08:15:51 > ssh -V OpenSSH_9.0p1 Ubuntu-1ubuntu8.7, OpenSSL 3.0.8 7 Feb 2023
For 2, step iv, I suggest wrapping the snippet with a test for a WSL2 environment: