unofficial mirror of help-guix@gnu.org 
 help / color / mirror / Atom feed
From: "Matthew Todd" <matthew@zerobitcoder.net>
To: help-guix@gnu.org
Subject: Guix pull channels via git over ssh with ed25519 host key
Date: Sun, 29 Dec 2024 05:09:03 -0800	[thread overview]
Message-ID: <0b9479a3-abd7-4ccf-a8e7-214b34d83a4f@app.fastmail.com> (raw)

Hi GNU Guix developers / packagers,

I have a couple private Guix channels on a git server on my LAN. Using a recent guix binary I am unable to pull from these channels. I believe the issue is that the libssh2 package in gnu/packages/ssh.scm is compiled with libgcrypt (--with-libgcrypt), which causes it to disable support for ed25119 hostkeys, and possibly others. This leaves only "ssh-rsa" available for libgit2, which appears to be failing because libssh2 doesn't support it due to being deprecated. Leaving no host key methods available.

Example channels.scm excerpt:
    (channel
      (name 'my-guix-channel)
      (url "git@my-git-server.local:repos/my-guix-channel.git")
      (branch "master"))

The error:
    "guix pull: error: Git error: failed to start SSH session: Unable to exchange encryption keys"


If Guix does not intend to support git over ssh, then I recommend adding something to the Guix documentation about this. Even if support is intended long term, it would help to mention which protocols are currently supported / working versus which are experimental.

If Guix does intend to support git over ssh, then I suspect the fix will require some subset of:
* Updating the libssh2 Guix package
* Switching the Guix libgit2 package from libssh2 to OpenSSH
* Switching the Guix libssh2 package away from libgcrypt to libopenssl
* Updates to libssh2 upstream so that it supports ed25119 when configured with libgcrypt. (Might also apply to other host key methods as well. From one libssh2 Github issue I read, this may require changes to libgcrypt as well - I'm not sure.)


Additional info:
* Full disclosure: my knowledge of libgit2 and libssh2 was zero before starting to debugging this issue a couple days ago. I could be missing some things.
* I am running Guix on a Debian foreign distro, installed via the Debian apt package manager. Debian stable "bookworm" version 12.8.
* "my-git-server.local" is another Debian stable on my LAN with a git user serving git repositories over SSH. This was in place and working prior to my starting with Guix. It is the default sshd install, with the only change being to disable password authentication. No changes to host key or kex algorithms.
* My ssh key is an ssh-ed25519. From what I remember, it was created with the default Debian ssh client settings 3 or 4 years ago. Client configuration in ~/.ssh/config for the git server host only specifies git user, ssh key to use, and to add the ssh key to the ssh-agent automatically. No changes to host key or kex algorithms.
* It appears to be necessary to add the SSH key for the git server to the ssh agent prior to calling `guix pull`.
* The Debian provided guix binary `/usr/bin/guix`, version 1.4.0 (from 2022), is able to use the channel definitions with git over SSH. I have not investigated why this is.
* The Guix provided guix binary `$HOME/.config/guix/current/bin/guix` I was testing with is version f3f3cb06b0a852f96a1f76f6168307583e6dfac5 (updated around 2024-12-27).
* By default, the Guix provided guix is using libgit2 (version 1.8.4), which uses libssh2 (version 1.10.0), to connect to the git server over SSH.
* libgit2 provides a command line interface ("git2") which supports cloning repositories. Installing it (via guix) and calling it gives the same error. So the issue is not with Guix code itself. All of my subsequent testing was via this command line tool: "git2 clone git@my-git-server.local:repos/some-git-repo.git /tmp/some-git-repo".
* guix provided (and Debian provided) standard git binaries are able to clone the guix channel without issue. Only libgit2 has the issue.
* From the log message + gdb, I see that the error is coming from within libssh2. Specifically, kex_agree_kex_hostkey manages to find a kex algorithm that the client and host agree on, but then fails on the host key agreement. Because libssh2 does not include "ssh-rsa" as one of its allowed host key algorithms:
    "Breakpoint 2, kex_agree_instr (haystack=0x593adf "rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519", haystack_len=57, needle=0x56f5b0 "ssh-rsa", needle_len=7) at kex.c:3296"
* The libssh2 project has released versions 1.11.0 and 1.11.1. Using guix package transformation option `--with-source` (plus --without-tests and some options to enable debugging) when installing libssh2, I tried both. They gave the same error message.
** FYI: libssh2 1.11.0 and 1.11.1 fail packing to build due to some tests. Hence --without-tests.
* For further investigation, I grabbed libssh2-1.11.1 and libgit2-1.8.4 code and modified them to print libssh2 trace information and additional debug prints that I added. libgit2 uses the known_hosts to determine that the following host keys are preferred: "ssh-ed25519,ecdsa-sha2-nistp256,ssh-rsa." It passes this to libssh2's libssh2_session_method_pref, which filters out unsupported methods, leaving only "ssh-rsa." Looking at the filtering code, it uses libssh2's hostkey.c's hostkey_methods array, which is defined at compile time using #ifdefs. I confirmed that the methods for ed25519 are not included. I believe this is because LIBSSH2_ED25519 is #defined to "0" in libssh2's libgcrypt.h. (In libssh2's openssl.h it is #defined based on OPENSSL_VERSION_NUMBER. And it only seems to be #defined to a non-zero value for openssl.)
* libgit2 version 1.8.0 introduced the ability to use OpenSSH instead of libssh2, by providing `-DUSE_SSH=exec` during the build. This gave yet another error. I did not pursue this option any further and cannot currently comment on its feasibility. The error:
    "fatal: bad argument
    git2: could not read refs from remote repository"
* The libgit2 project has released version 1.9.0 in the past day. I have not tried it.
* I tried a few of the older versions of libgit2 (the ones packaged in Guix already). I got the same error.
* I have not tried using older versions of libssh2. I suspect they will not work as the SSH server probably no longer supports SHA1, and older libssh2 versions (I think) do not support upgrading the SHA.



I hope this is helpful.


P.s.: Guix's package transformation options were awesome and made debugging and testing this a lot easier than I was expecting. Especially given this was my first serious foray into using more advanced Guix features. Awesome work. Thank you for making GNU Guix.

Cheers,
Matthew Todd
matthew@zerobitcoder.net


                 reply	other threads:[~2024-12-30 18:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0b9479a3-abd7-4ccf-a8e7-214b34d83a4f@app.fastmail.com \
    --to=matthew@zerobitcoder.net \
    --cc=help-guix@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).