1

I have been using KeePassXC as a password manager for a while and I've been quite happy with it. Today I decided to try to set it up as as ssh agent. The platforms of interest for me are Windows and Linux. I followed this post here from superuser and added my ssh keys to KeePassXC. As advertised, if the database is unlocked and I run ssh-add -l I see the keys from KeePassXC, and when the database is locked, I can't see the keys.

The problem is now in setting the values in ~/.ssh/config correctly. I would like to avoid the agent to just try all available ssh keys. So I added the following two lines to the top of my ~/.ssh/config

IdentitiesOnly yes
PasswordAuthentication no

As described in the other superuser post, I added the public key to the ~/.ssh/config

Host bitbucket
    HostName bitbucket.mycompany.com
    User Sito
    IdentityFile C:\Users\Sito\.ssh\bitbucket.pub

The other post then claims that

ssh will use the correct key from KeePassXC if it's added to agent.

So I ran

> ssh -vvv -T git@bitbucket.mycompany.com
...
debug1: Offering public key: C:\\Users\\Sito\\.ssh\\bitbucket.pub RSA HASH explicit agent
...
debug1: Server accepts key: C:\\Users\\Sito\\.ssh\\bitbucket.pub RSA HASH explicit agent
...
Authenticated to bitbucket.mycompany.com ([IP]:PORT)
...
shell request failed on channel 0

But the moment I try to git clone a repository form our server, I get the following error

> git clone ssh://git@link_to_repo
Load key "C:\\Users\\Sito\\.ssh\\bitbucket.pub": invalid format
git@bitbucket.mycompany.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.

I again tried to debug this with git config --global core.sshCommand='ssh-vvv' but the last part before the invalid format message is just

...
debug1: Server accepts key: C:\\Users\\Sito\\.ssh\\bitbucket.pub RSA HASH explicit
debug3: sign_and_send_pubkey: using publickey with RSA HASH
debug3: sign_and_send_pubkey: signing using rsa-sha2-512 HASH
Load key "C:\\Users\\Sito\\.ssh\\bitbucket.pub": invalid format
...

The only difference to the ssh -T here seems to be that instead of explicit agent at the end it just says explicit. Any ideas on how to fix this?

Sito
  • 13

1 Answers1

0

The only difference to the ssh -T here seems to be that instead of explicit agent at the end it just says explicit. Any ideas on how to fix this?

That means it has no connection to the SSH agent emulated by KeePassX – and without that, it can't really do anything useful with only the public key.

The issue is that there exist several incompatible ports of OpenSSH to Windows – although they use fundamentally the same agent protocol, but they use it over different transports, as it took 20+ years for Windows to gain a Unix-compatible "local sockets" feature in 2016. (Sure, the Windows NT family had "named pipes" that did the job, but… some of those porting decisions date back to Windows 98, which did not have anything better than TCP, and even that was still brand new.)

So when you install Git on Windows 10 or later, you always end up with two of them:

  • The ssh that you're running from a regular command shell is a native port done by Microsoft and installed together with Windows 10, and it connects to its ssh-agent through an NT named pipe \\.\pipe\openssh-ssh-agent. (An unusual choice Microsoft made is that there is only one ssh-agent for all users, running as a system service, so it works without the SSH_AUTH_SOCK environment variable.)

  • The ssh that Git uses is an MSYS-based port installed together with Git, and it appears to use the traditional Cygwin method of emulating Unix local sockets on top of TCP sockets. It expects an SSH_AUTH_SOCK=/tmp/ssh-whatever environment variable as on Linux, and it expects that to point to a Unix-style socket path that the Cygwin runtime turns into a TCP connection to localhost:XYZ.

The two programs only happen to agree on what path ~/.ssh translates to, so they're both capable of finding the same ~/.ssh/config (and that's already a step up from Cygwin-based OpenSSH, yet another port that used to be popular back in the day – which had a completely separate home directory), but they're completely unable to talk to each other's ssh-agent instances.

KeePassX could provide support for both kinds of ssh-agent protocols (and I believe there are already bridges in various directions, just like Git itself comes with a bridge to PuTTY's "Pageant" agent that does the same thing a yet another incompatible way), but I don't know if it actually can do that.

So I would suggest the simpler option of forcing Git to use the Windows-bundled variant of OpenSSH, e.g. by specifying the full path to C:\Windows\System32\OpenSSH\ssh.exe, or by removing the Git-bundled OpenSSH outright (its own ssh.exe is located in C:\Program Files\Git).

When installing Git anew, these days you have the option to use the Windows OpenSSH port and skip the bundled one:

enter image description here

Before that, you used to have the option between using bundled OpenSSH versus PuTTY's plink.exe, which again had its own agent (Pageant) with an entirely incompatible protocol. Nowadays Pageant can be used with OpenSSH but it takes manual configuration.

grawity
  • 501,077