Not working on Arch distro
chtsai0105 opened this issue · 6 comments
Hi, I want to migrate my OS from Ubuntu to Arch. When I insert the Yubikey, both Windows and Ubuntu can recognize the smartcard and print the status. However, I found that the pageant is not working on Arch.
In Windows powershell:
In Ubuntu:
In Arch:
I then check whether socat is running and found that it only run on the first-executed wsl instance. If I run Ubuntu first then socat won't run properly on Arch. Although I did try to run Arch before Ubuntu but still have no luck. However, I noticed there is a different behavior between these two OS.
When socat successfully run on Ubuntu, only the socat-rendered gpg-agent is found in jobs:
When socat run on Arch. it would behave like in Ubuntu in the beginning:
However, when I checked the smartcard by gpg --card-status, it take a few second and shows an error "can't connect to the agent: End of file"
When I ran it second time it became "No such device":
Later I checked the jobs with htop again and found that the standard gpg-agent is up:
I suspect that should be the reason which cause the pageant failed on Arch.
Another possibility would be the fish shell since I'm using fish in Arch and bash in Ubuntu, I'll check whether the pageant can work on fish on Ubuntu or bash on Arch.
Hello, sorry for the late response.
I then check whether socat is running and found that it only run on the first-executed wsl instance. If I run Ubuntu first then socat won't run properly on Arch.
This behavior is expected as WSL does not isolate the network namespaces of multiple WSL-Instances. Therefore the socat process is already listening and the start shell script does not invoke another one.
I suspect that Arch Linux by it's nature is using more recent versions of the supplied apps. Which may break something I recall that there was another issue with similar problems. Can you have a look into #7?
Did you ran the gpg addon in verbose mode to see if the request is acutally hitting the forwarding process?
I've recently switched to Windows 11, where I noticed I couldn't get the older GnuPG 2.2.28 version thats bundled with Gpg4win to work with my YubiKey (gpg --card-status
wouldn't detect it), so after a bit of searching I found official w32 builds of the latest GnuPG versions: https://www.gnupg.org/ftp/gcrypt/binary/
With the gnupg-w32-2.3.2_20210824.exe
GnuPG 2.3.2 build I could get my YubiKey to work flawlessly with GPG and SSH in Windows and SSH in WSL, however I still had the same issue @chtsai0105 described with GPG not working inside my Arch Linux WSL.
After looking through wsl2-ssh-pageant's source I noticed it's by default looking for the gnupg socket in %USERPROFILE%\AppData\Roaming\gnupg
:
Line 151 in 901de44
however mine were actually placed in %USERPROFILE%\AppData\Local\gnupg
(might be related to the more recent GnuPG version, just the path for the sockets changed though, all the other gnupg files like the keyrings are still in %USERPROFILE%\AppData\Roaming\gnupg
).
After changing that part of the code and recompiling (mostly because I was too lazy to figure out the escaping for --gpgConfigBasepath
, probably something like --gpgConfigBasepath C:\\Users\\USERNAME\\AppData\\Local\\gnupg
) it's now working perfectly inside WSL as well.
So I'd recommend trying two things:
- Make sure your
%USERPROFILE%\AppData\Roaming\gnupg
actually contains theS.gpg-agent
file wsl2-ssh-pageant is looking for by default, if not, set--gpgConfigBasepath
to the full path containing that file (see above). - Try updating your GnuPG to 2.3.2 and repeat step 1
Running into the same thing as #26 (comment) trying to use gpgConfigBasepath but having trouble getting the escaping with socat correct.
An example with a working path would be really nice.
I got it working i zsh with this (nenver managed to get correct path using backslashes)
if ! ss -a | grep -q "$GPG_AGENT_SOCK"; then
rm -rf "$GPG_AGENT_SOCK"
wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
if test -x "$wsl2_ssh_pageant_bin"; then
(setsid nohup socat UNIX-LISTEN:"$GPG_AGENT_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin --gpgConfigBasepath C\:/Users/per.lind/AppData/Local/gnupg --gpg S.gpg-agent" >/dev/null 2>&1 &)
else
echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
fi
unset wsl2_ssh_pageant_bin
fi```
You could also use gpgconf.exe --list-dirs
to support both Local
and Roaming
gpg_config_basepath=$(gpgconf.exe --list-dirs | grep socketdir | cut -f2- -d: | tr -d '\r\n')
# escape characters so that C%3a\Users\USER\AppData\Roaming\gnupg becomes C\:/Users/USER/AppData/Roaming/gnupg
gpg_config_basepath=${gpg_config_basepath//\\/\/}
gpg_config_basepath=${gpg_config_basepath/\%3a/\\\:}