III. YubiKey Windows SSH Client Configuration

Overview

This guide is intended to leverage an already provisioned PIV Smartcard to be automatically loaded at user login used for SSH authentication. The process works by using pageant as an ssh-agent to load the certificates as SSH keys via the Microsoft CryptoAPI (CAPI) and provide the necessary APIs for user interaction for PIN prompts. This CAPI interaction is critical as it provides an OS-integrated secure PIN prompt for your YubiKey. The secondary piece of software, wsl-ssh-pageant is used as a shim between pageant and various ssh/ssh-agent aware applications such as:

Most users will be fine with Putty-CAC.

Those who wish to have more customizability or an interface similar to a Unix system may want to continue with Win32-OpenSSH.


Prerequisites

Putty-CAC

Setup

Install Software

Once a Smartcard has been setup and configured (choose 1 of the 3 options):

  • Download and install putty-cac

    OR

  • Chocolatey Install:

    choco install putty-cac -y

    OR

  • SCCM Software Center Install:

Load Certificates into Pageant

This step is optional and only shown to outline the mechanics of manually loading certs into Pageant. This step only provides certificate use while Pageant is running. Once the application exits and restarts, no certificates will be loaded and this process must be manually repeated. Therefore the next step outlines an automated method.

 Click here to expand...
  1. Ensure the YubiKey is inserted into the machine and has certificates installed on it
  2. Start Pageant

  3. "Add CAPI Cert" to add your certificate to Pageant

  4. In Putty, expand "SSH" section, click on "Auth"; check "Allow agent forwarding" to forward your creds in Pageant.

Configure Shortcuts for Automatic Certificate Loading (putty)

There are two main issues with these applications that can lead to frustration:

  • Pageant does not remember what certificates you loaded in between application restarts.

To solve these problems, we will create shortcuts located in the startup folder within the users individual profile to autostart these applications on logon.

These shortcuts will autoload the certs on the YubiKey into Pageant ensuring they are ready to be used when needed.

  • This is for Windows CA-issued Certificates

    Configure Pageant from the putty-cac install to automatically load key(s) (via PowerShell):

    # Create shortcut to automatically load Certificates into Pageant on startup in user's shell:startup location, Obtain only the user certificates that match the yubicosc template
    
    $CertsToAdd = (Get-ChildItem Cert:\CurrentUser\My | ? { try { $_.Extensions.format(1) -match "yubicosc|1.3.6.1.4.1.311.21.8.1243817.6959666.9847190.948791.4713993.230.7565430.9626371" } catch {} }).thumbprint | % { $argument += "CAPI:$($_) " }; $argument 
    $objShell = New-Object -ComObject ("WScript.Shell")
    $objShortCut = $objShell.CreateShortcut($env:USERPROFILE + "\Start Menu\Programs\Startup" + "\pageant-startup-cert-autoload.lnk")
    $objShortCut.TargetPath = "C:\Program Files\PuTTY\pageant.exe"
    $objShortCut.Arguments = $argument
    $objShortCut.Arguments = $objShortCut.Arguments + " -certauthprompting"
    $objShortCut.Save()

    This can be modified to load specific keys by modifying the $CertsToAdd line DnsNameList matching OR by removing that line and statically setting the text in the $objShortCut.Arguments with the following syntax (note the space):

    $objShortCut.Arguments = "CAPI:ad3930cf31ac1c9fa135d4e170cdb722d4da02d5 CAPI:1231fa1e170cd35d4e170cdb722d4da02f4"
  • This is for Self-Signed Certificates
    This also assumes that you used your username for Self-Signed Certificate and is the logged in user on the computer ($env:username); if not, replace $env:username in first line with your actual username.

    Configure Pageant from the putty-cac install to automatically load key(s) (via PowerShell):

    # Create shortcut to automatically load Certificates into Pageant on startup in user's shell:startup location, Obtain only the user certificates that matches username
    
    $CertsToAdd = (Get-ChildItem Cert:\CurrentUser\My | ? { try { $_.Subject -match "^CN=$env:username" } catch {} }).thumbprint | % { $argument += "CAPI:$($_) " }; $argument 
    $objShell = New-Object -ComObject ("WScript.Shell")
    $objShortCut = $objShell.CreateShortcut($env:USERPROFILE + "\Start Menu\Programs\Startup" + "\pageant-startup-cert-autoload.lnk")
    $objShortCut.TargetPath = "C:\Program Files\PuTTY\pageant.exe"
    $objShortCut.Arguments = $argument
    $objShortCut.Arguments = $objShortCut.Arguments + " -certauthprompting"
    $objShortCut.Save()

Configure Putty-CAC Agent Forwarding

  • In Putty, expand SSH section, click on Auth; check Allow agent forwarding to forward your creds in Pageant.
  • Go back to Session on the left hand menu
  • Then click on Default Session and then Save to save these settings as your default


Verify

Shortcut Verification

  • You can verify the creation of the shortcuts by:
  • Open the Start menu
  • Type "run"
  • In the Run dialog type:

    shell:startup

  • Verify that shortcut created above is here named 'pageant-startup-cert-autoload'

  • You can verify the startup params by right clicking and selecting properties

  • Double click shortcut 'pageant-startup-cert-autoload' to start it immediately rather than waiting on next logon


Usage

Example of using Putty-CAC to SSH

  1. Ensure Pageant is running
  2. Launch Putty
  3. Enter hostname of server that you are trying to access
  4. In the left hand Category listing, select "SSH" > "Auth" and check "Allow agent forwarding"
  5. Now click the "Open" button in the lower right hand corner
  6. Enter your username and then PIN when presented
  7. Success!

Win32-OpenSSH (Optional)

Optional setup for OpenSSH for Windows. OpenSSH for Windows presents a more Unix-like setup. This will require the install of Putty-CAC, mainly for the pageant.

It's recommended to go through the following steps of the Putty-CAC install and setup:

Setup

Install Software

It is recommended that you uninstall ANY OpenSSH provided through the OS as these are not updated as frequently:

Get-WindowsCapability -online | ? {$_.name -like "*SSH*" -and $_.State -eq "Installed"} | Remove-WindowsCapability -Online -Name $_

Configure Shortcuts for Automatic Certificate Loading (Win32-OpenSSH)

There are two main issues with these applications that can lead to frustration:

  • wsl-ssh-pageant does not have a simple way to autoload on logon.

To solve these problems, we will create shortcuts located in the startup folder within the users individual profile to autostart these applications on logon.

These shortcuts will launch the wsl-ssh-pageant shim and autoload the certs on the YubiKey into Pageant ensuring they are ready to be used when needed.

  • Configure wsl-ssh-pageant to automatically load on user logon:

    # Create Shortcut for wsl-ssh-pageant is user's shell:startup location
    
    $wslsshpageantlocation = Invoke-Command -ScriptBlock {where.exe /R C:\Users wsl-ssh-pageant-*-gui.exe}  #this works with downloaded exe from GitHub
    $wslsshpageantlocation = Invoke-Command -ScriptBlock {where.exe wsl-ssh-pageant-gui.exe} #this works with chocolately install
    $objShell = New-Object -ComObject ("WScript.Shell")
    $objShortCut = $objShell.CreateShortcut($env:USERPROFILE + "\Start Menu\Programs\Startup" + "\wsl-ssh-pageant-startup.lnk")
    $objShortCut.TargetPath = $wslsshpageantlocation
    $objShortCut.Arguments = "-systray -winssh ssh-pageant"
    $objShortCut.Save()

PowerShell $PROFILE Environment Variable setup

If you plan to use Win32-OpenSSH you will need to configure an environment variable that points to the wsl-ssh-pageant shim:

  • Powershell $profile additions
    • If you leverage a PowerShell profile and wish to use native win32 OpenSSH you must set the SSH_AUTH_SOCK environment variable
    • Edit your PowerShell profile to add the following (notepad $profile)

      #if putty-cac pageant running and the wsl shim are running, configure the environment
      if ((Get-Process pageant) -and (Get-Process wsl-ssh-pageant*)) {
          #we are using pageant, load shim from wsl-ssh-pageant
          $env:SSH_AUTH_SOCK = '\\.\pipe\ssh-pageant'
      }

Verify

Shortcut Verification

  • You can verify the creation of the shortcuts by:
  • Open the Start menu
  • Type "run"
  • In the Run dialog type:

    shell:startup

  • Verify that shortcut created above is here named 'wsl-ssh-pageant-startup'

  • You can verify the startup params by right clicking and selecting properties
  • Double click shortcut 'wsl-ssh-pageant-startup' to start it immediately rather than waiting on next logon

Usage

This is a walkthrough of using Win32-OpenSSH with certificate based authentication provided by Pageant via the wsl-ssh-pageant shim.

  1. Ensure that your environment contains the Win32-OpenSSH installation path

    PS > $env:Path -split ";" | sls ssh
    
    C:\Program Files\OpenSSH
    
    
  2. If this does not exist, you can add it (note you must close and re-open your terminal for these to be picked up)

    #Machine Wide (must be run with Administrative privileges)
    $newPath = "$env:ProgramFiles\OpenSSH;" + [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::Machine)
    [Environment]::SetEnvironmentVariable("PATH", $newPath, [EnvironmentVariableTarget]::Machine)
    
    #User Level
    $newPath = "$env:ProgramFiles\OpenSSH;" + [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::User)
    [Environment]::SetEnvironmentVariable("PATH", $newPath, [EnvironmentVariableTarget]::User)
  3. SSH to a machine (-A is agent forwarding)

    ssh.exe -A machine.ad.rit.edu -l username
  4. You will be prompted to enter your PIN


  5. Success!

  6. You can automatically configure Agent forwarding (to avoid typing '-A' every time):
    • edit ~/.ssh/config

      > notepad $env:USERPROFILE\.ssh\config
    • add the following:

      Host *
        ForwardAgent yes

WSL Version 1 (Work In Progress)

Note: These steps only work on WSL 1. For WSL 2, there's another section below.

Optional setup for WSL for Windows. WSL offers a virtual Linux install running on native hardware, alongside the Windows host OS. This offers a lot more flexibility compared to Putty. This will also require the install of Putty-CAC, for the pageant.

It's required to go through the following steps of the Putty-CAC install and setup. You should have Pageant running and the certificate loaded, as well as auto start configured:

Setup

Note: This will require admin access. If you don't have that, you'll need permission from someone who does.

  1. To install WSL and the required features, type the following in Powershell, run as administrator:

    wsl --install --no-distribution
  2. Restart your PC.
  3. Now you'll need to install a distro. Run the list command to get the available options:

    #to change the installed distro, use the following
    wsl --list --online
    #this produces a list of available distros. Pick one and then run:
    wsl --install -d [distro name]
  4. You'll find the distro in the start menu, like you would any other program. It will also show up as an option in Windows Terminal, if you use that:

The first launch will take a while and ask you to create a user account. This account is for the local Linux install and can be whatever you want.

Next, you'll need to set up wsl-ssh-pageant. Like Pageant downloaded with Putty, we need this to start automatically on user login. To do that, we'll make a shortcut in the Windows startup folder, which automatically starts the program with the PC.

  1. Download the wsl-ssh-pageant-amd64-gui executable from https://github.com/benpye/wsl-ssh-pageant/releases
  2. Create a folder for wsl-ssh-pageant to use. It can be named whatever you want, but make sure you copy the full path to the folder.
  3. Configure wsl-ssh-pageant to automatically load on user logon by entering these commands in Powershell. You'll need to specify the location you created a socket folder in one of the steps.

    # Create Shortcut for wsl-ssh-pageant in user's shell:startup location
    
    $wslsshpageantlocation = Invoke-Command -ScriptBlock {where.exe /R C:\Users wsl-ssh-pageant-amd64-gui.exe}  #this works with downloaded exe from GitHub
    $objShell = New-Object -ComObject ("WScript.Shell")
    $objShortCut = $objShell.CreateShortcut($env:USERPROFILE + "\Start Menu\Programs\Startup" + "\wsl-ssh-pageant-startup.lnk")
    $objShortCut.TargetPath = $wslsshpageantlocation
    #DON'T FORGET TO PUT YOUR SOCKET PATH IN
    $objShortCut.Arguments = "-systray --wsl [enter full socket path here]" --force
    $objShortCut.Save()

Verify

Shortcut Verification

  • Open the Start menu
  • Type "run" and then press enter
  • In the Run dialog type:

    shell:STARTUP

  • Verify that shortcut created above is here named 'wsl-ssh-pageant-startup'

  • Log out and log back in to make sure your shortcut starts properly. If it works, you should see a key icon in your system tray.

Usage

In order to use SSH with WSL, you'll need to have a distro installed and Pageant configured. I'm using Ubuntu in these examples, but SSH commands are generally very similar across Linux distros.

You will need to run the export command in WSL every time you restart your PC. Make sure the path is correct.


  • In WSL, run the following command:
export SSH_AUTH_SOCK=/mnt/c/[insert path to socket here]


This will connect WSL to the socket that Pageant is running on.

After this, you can run SSH:

ssh -A [address]


The -A in this case is the same as checking the "forwarding agents" option in Putty. The server should ask you for your username and accept your yubikey as a password.


WSL 2 Setup (wsl2-ssh-pageant, WIP)

Optional setup for WSL for Windows. WSL offers a virtual Linux install running on native hardware, alongside the Windows host OS. This offers a lot more flexibility compared to Putty. This will also require the install of Putty-CAC, for the pageant.

It's required to go through the following steps of the Putty-CAC install and setup. You should have Pageant running and the certificate loaded, as well as auto start configured:

Setup

Note: This will require admin access. If you don't have that, you'll need permission from someone who does.

  1. You will need to download the Linux kernel package for WSL 2. It can be found at this link: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
  2. To install WSL and the required features, type the following in Powershell, run as administrator:

    wsl --set-default-version 2
    wsl --install --no-distribution
  3. Restart your PC.
  4. Now you'll need to install a distro. Run the list command to get the available options:

    #to change the installed distro, use the following
    wsl --list --online
    #this produces a list of available distros. Pick one and then run:
    wsl --install -d [distro name]
  5. You'll find the distro in the start menu, like you would any other program. It will also show up as an option in Windows Terminal, if you use that:

The first launch will take a while and ask you to create a user account. This account is for the local Linux install and can be whatever you want.

Next you'll need the WSL2 fork of wsl-ssh-pageant. This can be downloaded from here: https://github.com/BlackReloaded/wsl2-ssh-pageant/releases

The following creates a symlink to the windows executable and executes it on startup of WSL. This links the Windows SSH keys into WSL. It puts those in the .ssh folder of your home folder, which will be hidden in regular ls commands. Make sure to use ls -la to see it!

Once you have the file downloaded, do the following in the WSL terminal: (replace the windows destination with the path to your downloaded executable)

windows_destination="/mnt/c/Users/Public/Downloads/wsl2-ssh-pageant.exe"
linux_destination="$HOME/.ssh/wsl2-ssh-pageant.exe"
# Set the executable bit.
chmod +x "$windows_destination"
# Symlink to linux for ease of use later
ln -s $windows_destination $linux_destination
  1. Next, edit your .bashrc file with the following:
  2. export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
    if ! ss -a | grep -q "$SSH_AUTH_SOCK"; then
      rm -f "$SSH_AUTH_SOCK"
      wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
      if test -x "$wsl2_ssh_pageant_bin"; then
        (setsid nohup socat UNIX-LISTEN:"$SSH_AUTH_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin" >/dev/null 2>&1 &)
      else
        echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
      fi
      unset wsl2_ssh_pageant_bin
    fi
  3. In powershell, type wsl --shutdown.
  4. Open a new WSL window.

Verify/Usage

To verify these steps were successful, you'll need to attempt an SSH connection.

In order to use SSH with WSL, you'll need to have a distro installed and Pageant configured. I'm using Ubuntu in these examples, but SSH commands are generally very similar across Linux distros.

ssh -A [address]


The -A in this case is the same as checking the "forwarding agents" option in Putty. The server should ask you for your username and accept your yubikey as a password. If your setup was successful, you'll see a popup asking you to verify the connection.