wsl-ssh-pageant icon indicating copy to clipboard operation
wsl-ssh-pageant copied to clipboard

Support for WSL2

Open AngellusMortis opened this issue 5 years ago • 44 comments

According to a similar project, https://github.com/rupor-github/wsl-ssh-agent/issues/3, it seems this is not possible yet, but I just wanted to make an issue to cover it for anyone else was doing some digging.

It seems that the Windows/Unix socket interoperability does not work yet for WSL 2.

AngellusMortis avatar Dec 10 '19 18:12 AngellusMortis

Thanks for the issue @AngellusMortis , I am aware of this limitation. There is a workaround currently which works with npiperelay and the Windows SSH support. It's possible to bridge Pageant to Windows SSH and then use npiperelay to bridge that into WSL 2. If there is interest this could possibly be added in the tool itself, what do you think?

benpye avatar Feb 02 '20 06:02 benpye

@benpye How do I run npiperelay correctly?

I have tried this

joel@JOEL-XPS15:/mnt/c/Users/Joel$ socat UNIX-LISTEN:/home/joel/.ssh/authsock,fork,group=joel,umask=007 EXEC:"npiperelay.exe -ep -s //./pipe/ssh-pageant",nofork
/usr/local/bin/npiperelay.exe: Invalid argument

But whenever I try to use the agent I get a /usr/local/bin/npiperelay.exe: Invalid argument error.

I have this: export SSH_AUTH_SOCK=/home/joel/.ssh/authsock as well

What's the magic syntax?

pearj avatar Mar 23 '20 10:03 pearj

Woops! I totally forgot about this thread. I use the following command line - I guess you need to pass the full path to npiperelay.exe.

socat EXEC:"/mnt/c/Users/benpy/go/bin/npiperelay.exe /\/\./\pipe/\ssh" UNIX-LISTEN:/tmp/wsl-ssh-pageant.socket,unlink-close,unlink-early,fork

benpye avatar Apr 08 '20 22:04 benpye

Ahh awesome thanks. I think it turned out "Invalid argument" was because I was trying to run windows binaries from a windows working directory. You can see I was using /mnt/c/Users. When I changed to the Linux home directory it worked fine.

Out of interest how do you start socat? I tried to get systemd to run it for me, but it just keeps crashing.

I have:

[Service]
User=joel
Type=Simple
ExecStart=/usr/bin/socat -u EXEC:"/mnt/c/Users/Joel/go/bin/npiperelay.exe //./pipe/ssh-pageant" UNIX-LISTEN:/tmp/wsl-ssh-pageant.socket,unlink-close,unlink-early,fork  

But it dies with:

Apr 11 23:03:23 JOEL-XPS15 systemd[1]: Started ssh-agent-socat.service.
Apr 11 23:03:23 JOEL-XPS15 socat[3045]: 2020/04/11 23:03:23 socat[3045] E waitpid(): child 3046 exited with status 1
Apr 11 23:03:23 JOEL-XPS15 systemd[1]: ssh-agent-socat.service: Main process exited, code=exited, status=1/FAILURE
Apr 11 23:03:23 JOEL-XPS15 systemd[1]: ssh-agent-socat.service: Failed with result 'exit-code'.

pearj avatar Apr 11 '20 13:04 pearj

I've added this to my ~/.bashrc

if [ ! -S /tmp/wsl-ssh-pageant.socket ] && [ -z "$TMUX" ]; then
    echo "Starting socat relay to ssh-pageant"
    tmux new-session -d -s socat-ssh-agent
    tmux send-keys '/usr/bin/socat EXEC:"/mnt/c/Users/Joel/go/bin/npiperelay.exe //./pipe/ssh-pageant" UNIX-LISTEN:/tmp/wsl-ssh-pageant.socket,unlink-close,unlink-early,fork' C-m
fi

export SSH_AUTH_SOCK=/tmp/wsl-ssh-pageant.socket

Using tmux seems a bit blah, but it gets the job done. Simply backgrounding the socat command in the ~/.bashrc with & was making VSCode hang when starting up inside WSL 2

pearj avatar Apr 11 '20 13:04 pearj

Adding this to ~/.bashrc

kill -9 $(ps x | grep npiperelay | grep -v grep | awk '{ print $1 }')
setsid nohup socat EXEC:"/mnt/c/work/ssh/npiperelay/npiperelay.exe /\/\./\pipe/\ssh-pageant" UNIX-LISTEN:/tmp/wsl2-ssh-agent.sock,unlink-close,unlink-early,fork >/dev/null 2>&1 &
export SSH_AUTH_SOCK=/tmp/wsl2-ssh-agent.sock

seems to work for me, both in Windows Terminal and VSCode

florin-saftoiu avatar Jun 08 '20 23:06 florin-saftoiu

I struggeled much to get this working. I found out that my pipe, that needs to be passed to npiperelay, had a different name. You can use this powershell command to check which pipes with "ssh" in name exist on your system. [System.IO.Directory]::GetFiles("\\.\\pipe\\") | Select-String -Pattern ssh for me it was \\.\\pipe\\openssh-ssh-agent

Pumba98 avatar Jun 09 '20 11:06 Pumba98

WSL v2 is public builds now (may update, ver 2004). Is this limitation still a factor? Since updating to WSLv2 I'm just getting public key permission denied to my servers (i.e. it isn't working!)

tombowditch avatar Jul 18 '20 13:07 tombowditch

The only two issues I have with https://github.com/benpye/wsl-ssh-pageant/issues/33#issuecomment-640935516 are that:

  1. WSL hangs when trying to close WSL windows (you have to CTRL+C to get it to close)
  2. The first WSL window that gets opened displays this warning:

    kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

To solve issue 2, I am using this:

EXISTING_RELAY_PIDS=$(ps x | grep npiperelay | grep -v grep | awk '{ print $1 }')

if [[ ! -z "${EXISTING_RELAY_PIDS}" ]]; then
  kill -9 ${EXISTING_RELAY_PIDS}
fi

setsid nohup socat \
  EXEC:"/mnt/c/Users/MY_USERNAME/bin/npiperelay.exe /\/\./\pipe/\ssh-pageant" \
  UNIX-LISTEN:/tmp/wsl2-ssh-agent.sock,unlink-close,unlink-early,fork >/dev/null 2>&1 &

export SSH_AUTH_SOCK=/tmp/wsl2-ssh-agent.sock

GuyPaddock avatar Jul 21 '20 19:07 GuyPaddock

This variant of https://github.com/benpye/wsl-ssh-pageant/issues/33#issuecomment-640935516 worked better for me, and avoids the hang-at-close:

EXISTING_RELAY_PIDS=$(ps x | grep npiperelay | grep -v grep | awk '{ print $1 }')

if [[ -z "${EXISTING_RELAY_PIDS}" ]]; then
  socat \
    EXEC:"/mnt/c/Users/MY_USERNAME/bin/npiperelay.exe /\/\./\pipe/\ssh-pageant" \
    UNIX-LISTEN:/tmp/wsl2-ssh-agent.sock,unlink-close,unlink-early,fork >/dev/null 2>&1 &
fi

export SSH_AUTH_SOCK=/tmp/wsl2-ssh-agent.sock

GuyPaddock avatar Jul 21 '20 20:07 GuyPaddock

@GuyPaddock I'm using your variant, but when I try to ssh to somewhere within WSL, socat exits:

voltagex@Argentum:/mnt/c/Users/Adam$ ssh 10.1.1.2
[email protected]: Permission denied (publickey).
[1]+  Exit 1                  socat EXEC:"/mnt/c/Users/Adam/OneDrive/bin/npiperelay.exe /\/\./\pipe/\ssh-pageant" UNIX-LISTEN:/tmp/wsl2-ssh-agent.sock,unlink-close,unlink-early,fork > /dev/null 2>&1

ghost avatar Jul 26 '20 11:07 ghost

@voltagex Yeah, I'm seeing that too... not sure why socat isn't staying open.

GuyPaddock avatar Jul 26 '20 18:07 GuyPaddock

I just noticed @ BlackReloaded has sort of forked/borrowed some code from @benpye's project specifically for WSL2 (using socat): https://github.com/BlackReloaded/wsl2-ssh-pageant. That setup works for me. Just note that the docs say $HOME/.ssh/ than just the home directory (took me a couple of reads to pick up on that).

Mind you I'm using it with https://smartcard-auth.de/index-en.html for pageant in order to support my Yubikey.

Vashiru avatar Jul 28 '20 23:07 Vashiru

I just noticed @ BlackReloaded has sort of forked/borrowed some code from @benpye's project specifically for WSL2 (using socat): https://github.com/BlackReloaded/wsl2-ssh-pageant. That setup works for me. Just note that the docs say $HOME/.ssh/ than just the home directory (took me a couple of reads to pick up on that).

Mind you I'm using it with https://smartcard-auth.de/index-en.html for pageant in order to support my Yubikey.

I got wsl2-ssh-pageant working, However, not sure why in wsl2, I cannot make this work in my .zshrc. The socat process is running and the sock file is created, I can see it in ss -a, but ssh-add -l hang, I have to kill socat process and resource .zshrc, then it start working again. This behavior is same for weasel-pageant, I cannot eval and start weasel-pageant.exe in my .zshrc in wsl2, I have to run the eval outside my .zshrc or kill the socat process and re-source my .zshrc once my terminal started. WSL1 do not have this issu. Anyone have this issue in WSL2?

Thanks

ckuai avatar Aug 03 '20 18:08 ckuai

I just noticed @ BlackReloaded has sort of forked/borrowed some code from @benpye's project specifically for WSL2 (using socat): https://github.com/BlackReloaded/wsl2-ssh-pageant. That setup works for me. Just note that the docs say $HOME/.ssh/ than just the home directory (took me a couple of reads to pick up on that). Mind you I'm using it with https://smartcard-auth.de/index-en.html for pageant in order to support my Yubikey.

I got wsl2-ssh-pageant working, However, not sure why in wsl2, I cannot make this work in my .zshrc. The socat process is running and the sock file is created, I can see it in ss -a, but ssh-add -l hang, I have to kill socat process and resource .zshrc, then it start working again. This behavior is same for weasel-pageant, I cannot eval and start weasel-pageant.exe in my .zshrc in wsl2, I have to run the eval outside my .zshrc or kill the socat process and re-source my .zshrc once my terminal started. WSL1 do not have this issu. Anyone have this issue in WSL2?

Thanks

Well I didn't have any issues on Ubuntu 18.04, I do see something similar on Ubuntu 20.04. But in my case socat wasn't running and ssh-add -l gave me 'file not found'. I discovered that when I run the socat command in the terminal, it works just fine, but it wasn't doing it when I ran it via my .zshrc. My workaround / fix was to remove the if statement so it will always execute.

Vashiru avatar Sep 04 '20 11:09 Vashiru

Just sharing what worked for me - I was new to Windows named pipes, and it's not obvious in the above comments that you need to tell wsl-ssh-pageant to set up the named pipe:

I installed https://github.com/rupor-github/wsl-ssh-agent first because it includes a pre-built npiperelay.exe - I didn't want to have to create a Go build environment.

# in windows, set up a named pipe called ssh-pageant - NOTE: install it in a path with no spaces, it makes the socat command simpler:
"c:\wsl-ssh-agent\wsl-ssh-pageant-386.exe" --winssh ssh-pageant
# then from wsl, use socat to connect it to a socket file:
socat EXEC:"/mnt/c/wsl-ssh-agent/npiperelay.exe -ei -s //./pipe/ssh-pageant" UNIX-LISTEN:/tmp/wsl-ssh-pageant.socket,unlink-close,unlink-early,fork
# then tell ssh to use that socket
export SSH_AUTH_SOCK=/tmp/wsl-ssh-pageant.socket

johnorourke avatar Sep 14 '20 07:09 johnorourke

I'll try and have a dig into why this isn't working well. I've generally not had too much trouble with npiperelay and socat though it would be nice to avoid needing the npiperelay binary at the very least.

benpye avatar Nov 21 '20 07:11 benpye

@ckuai I'm experiencing the same issue.

judemille avatar Nov 30 '20 06:11 judemille

@ckuai I'm experiencing the same issue. Since the Nov win10 monthly update or after 20H2 feature update, the issue seems gone for me.

ckuai avatar Nov 30 '20 06:11 ckuai

Hi,

Are there any plans to incorporate WSL2 support into wsl-ssh-pageant? I'd rather not have to fumble with multiple utilities.

tomoyat1 avatar Jan 06 '21 04:01 tomoyat1

@ckuai Not sure why that would be true, unless you switched to WSL 1.

WSL 2 still has no support for AF_UNIX-based socket communication with Windows programs. (See https://github.com/microsoft/WSL/issues/4240)

kohenkatz avatar Jan 06 '21 23:01 kohenkatz

seems like that thread is alive https://github.com/microsoft/WSL/issues/4240 perhaps they'll close this issue in nearest future 🚶‍♂️ but for now wsl.exe --set-version Ubuntu 1 😄

madzohan avatar Jan 14 '22 21:01 madzohan

Wow, this was not easy. Added the steps here as a Gist, works without tmux, in different WSL2 windows, no issues or errors on start or logout. Tested with Pageant running on the Windows side.

Originally missed to set permissions and ownership of files, which meant that the pipe relay did not work when sourced in bashrc.

Sieboldianus avatar Jan 25 '23 09:01 Sieboldianus

For those that have issues using npiperelay due to false positives from antivirus software... if you are using pageant, you'll likely have the full PuTTY suite installed that includes plink.exe. You can use that to connect to pipes as well. My solution doesn't use wsl-ssh-pageant, and doesn't need npiperelay. I run below command as a systemd service in WSL, and export the corresponding socket path via .bashrc:

socat UNIX-LISTEN:/home/username/.ssh/pageant.sock,unlink-early,fork "EXEC:'"'"'"/mnt/c/Program Files/PuTTY/plink.exe"'"'" -serial //
./pipe/pageant.YOURUSERNAME.SOMERVALUE'"

In case you need to look up the pipe name for pageant, you can run this in powershell:

Get-ChildItem \\.\pipe\ | ?{ $_ -like "*pageant*" } | %{ $_.name }

My systemd unit file:

[Unit]
Description=SSH Pageant Forwarder

[Service]
Type=simple
User=fholzer
ExecStart=/usr/bin/socat UNIX-LISTEN:/home/wls-username/.ssh/pageant.sock,unlink-early,fork "EXEC:'"'"'"/mnt/c/Program Files/PuTTY/plink.exe"'"'" -serial //./pipe/pageant.windows-username.random-data'"

[Install]
WantedBy=default.target

fholzer avatar Feb 23 '23 22:02 fholzer

Turns out the random string is different on every reboot, at least for me, so have to figure out a way to automate this yet.

fholzer avatar Mar 17 '23 06:03 fholzer

@fholzer Just an idea: run the power-shell command in a startup task on logon and write output to a file. Read that file as part of the ExecStart

capi avatar Mar 17 '23 08:03 capi

You can just run the PowerShell command from within WSL2

/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Command 'Get-ChildItem \\.\pipe\ | ?{ $_ -like "*pageant*" } | %{ $_.name }'

An alternative to the PowerShell command is to get pageant itself to write an OpenSSH configuration file, which you could parse the data from.

You would need to start pageant like this:

"C:\Program Files\PuTTY\pageant.exe" --openssh-config %USERPROFILE%\pageant.conf

Then %USERPROFILE%\pageant.conf has:

IdentityAgent \\.\pipe\pageant.pearj.2d30b9f59dc36f3f89423fe713164d35f9efb8b13fbe40022158982e0fa27d79

From WSL you can grab that with cut -d' ' -f2 /mnt/c/Users/pearj/pageant.conf | tr '\\' '/' which switches the slashes around.

pearj avatar Mar 19 '23 01:03 pearj

Mixing @fholzer and @pearj solutions:

#!/usr/bin/bash
plink="/c/Program\\\\ Files/PuTTY/plink.exe"
IdentityAgent=$(<pageant.conf)
IdentityAgent=${IdentityAgent:0:-1} # removes \r
IdentityAgent=${IdentityAgent##IdentityAgent } # cut it out
IdentityAgent=${IdentityAgent//\\/\/} # flips slashes

/usr/bin/socat \
   UNIX-LISTEN:/tmp/pageant.sock,unlink-early,fork \
  "EXEC:${plink} -serial ${IdentityAgent}"

alef avatar Apr 27 '23 18:04 alef

Do any of y'all have a step-by-step instruction manual on how to accomplish this?

I've been at this for about a month now, and I still can't get OpenGPG to work in my instance of WSL2, and I've tried just about everything, including all the examples here, and none of them worked.

I'm hoping I just overlooked something, but so far I'm able to get this to work.

KerickHowlett avatar May 12 '23 03:05 KerickHowlett

I roo have dealt with it for several days. My simple solution was to set my instance back to WSL1 🤮😂😩Von meinem iPhone gesendetAm 11/05/23 um 21:30 schrieb Kerick Howlett @.***>: Do any of y'all have a step-by-step instruction manual on how to accomplish this? I've been at this for about a month now, and I still can't get OpenGPG to work in my instance of WSL2, and I've tried just about everything, including all the examples here, and none of them worked. I'm hoping I just overlooked something, but so far I'm able to get this to work. Please help!

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

mircsicz avatar May 12 '23 13:05 mircsicz