如何通过SSH调用Rugged的check_connection?问题排查
check_connection始终返回false 问题重现
使用Ruby的Rugged库验证与GitHub私有仓库的SSH连接时,SSH密钥正确且无密码,但check_connection始终返回false,fetch操作抛出unsupported URL protocol异常。
测试代码
require 'pathname' require 'rugged' base = ARGV[0] || '.' base_fq = Pathname.new(base).realpath.to_s repo = Rugged::Repository.new base_fq puts repo.inspect remote = repo.remotes['origin'] puts "remote.name=#{remote.name}, remote.url=#{remote.url}, remote.fetch_refspecs=#{remote.fetch_refspecs}" credentials = Rugged::Credentials::SshKey.new( username: 'git', passphrase: nil, privatekey: File.expand_path('~/.ssh/id_rsa'), publickey: File.expand_path('~/.ssh/id_rsa.pub') ) puts credentials.inspect success = remote.check_connection(:fetch, credentials: credentials) puts "remote.check_connection(:fetch, credentials: credentials) returned #{success}" success = remote.fetch(credentials: credentials) puts "remote.fetch(credentials: credentials) returned #{success}"
程序输出
#<Rugged::Repository:60 {path: "/mnt/c/work/ruby/update/.git/"}> remote.name=origin, remote.url=git@github.com:mslinn/update.git, remote.fetch_refspecs=["+refs/heads/*:refs/remotes/origin/*"] #<Rugged::Credentials::SshKey:0x00007fee350db648 @username="git", @publickey="/home/mslinn/.ssh/id_rsa.pub", @privatekey="/home/mslinn/.ssh/id_rsa", @passphrase=nil> remote.check_connection(:fetch, credentials: credentials) returned false lib/check_connection.rb:21:in `fetch': unsupported URL protocol (Rugged::NetworkError) from lib/check_connection.rb:21:in `<main>'
排查过程
SSH直接连接正常:通过
ssh github.com可成功验证身份,说明密钥本身有效:$ ssh github.com Warning: No xauth data; using fake authentication data for X11 forwarding. X11 forwarding request failed on channel 0 PTY allocation request failed on channel 0 Hi mslinn! You've successfully authenticated, but GitHub does not provide shell access. Connection to github.com closed.libssh2不读取
~/.ssh/config:Rugged依赖的libgit2使用libssh2实现SSH,但libssh2不支持读取系统的~/.ssh/config配置,因此该文件中的Host规则对Rugged无效。密钥类型兼容性问题:使用的是RSA SHA-2密钥,而旧版本libssh2(低于1.9.0)不支持RSA with SHA-2:
$ ssh-keygen -l -f ~/.ssh/id_rsa 1024 SHA256:Xdv1AE4QTd0NfrwOGVTamF/wxnvFufCtsOIoOXtX5Mw Administrator@CHLOE (RSA)Rugged初始未启用SSH特性:检查发现初始安装的Rugged缺少SSH支持:
$ irb irb(main):001:0> require 'rugged' => true irb(main):002:0> Rugged.libgit2_version => [1, 6, 3] irb(main):003:0> Rugged.features => [:threads, :https]重新安装Rugged并添加
--with-ssh参数后,SSH特性已启用:$ gem install rugged -- --with-ssh Building native extensions with: '--with-ssh' This could take a while... Successfully installed rugged-1.6.3再次验证特性:
$ irb irb(main):001:0> require 'rugged' => true irb(main):002:0> Rugged.features => [:threads, :https, :ssh]core.sshCommand对Rugged无效:配置git config core.sshCommand "ssh -vi ~/.ssh/id_rsa"后,git pull能显示调试信息,但Rugged不受影响——因为libgit2不使用系统SSH客户端,也不支持该配置项。SSH-agent测试失败:配置SSH-agent后改用
SshKeyFromAgent凭证,check_connection仍返回false:credentials = Rugged::Credentials::SshKeyFromAgent.new(username: 'git')程序输出:
#<Rugged::Repository:60 {path: "/var/work/ruby/update/.git/"}> remote.name=origin, remote.url=git@github.com:mslinn/update.git, remote.fetch_refspecs=["+refs/heads/*:refs/remotes/origin/*"] #<Rugged::Credentials::SshKeyFromAgent:0x00007fa290d169d0 @username="git"> remote.check_connection(:fetch, credentials: credentials) returned false
解决方法
1. 确保Rugged安装时启用SSH支持
已完成基础安装,但如果仍有问题,可指定libssh2路径重新安装:
gem install rugged -- --with-ssh --with-libssh2-dir=/path/to/libssh2
2. 更换兼容的密钥类型
由于旧版libssh2不支持RSA SHA-2,生成ECDSA或Ed25519密钥:
- 生成Ed25519密钥:
ssh-keygen -t ed25519 -C "your_email@example.com" - 将新公钥添加到GitHub账户,修改代码中的密钥路径:
credentials = Rugged::Credentials::SshKey.new( username: 'git', passphrase: nil, privatekey: File.expand_path('~/.ssh/id_ed25519'), publickey: File.expand_path('~/.ssh/id_ed25519.pub') )
3. 验证libssh2版本
确保系统安装的libssh2版本≥1.9.0:
pkg-config --modversion libssh2
版本过低则升级libssh2后重新安装Rugged。
4. 正确使用SSH-agent
如果使用SshKeyFromAgent,确保SSH-agent运行且密钥已添加:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 # 替换为你的新密钥路径
再运行Ruby程序。
内容的提问来源于stack exchange,提问作者Mike Slinn

