今天在Java项目中,使用JGit库用SSH协议拉取远端代码时,遇到不少错误,踩了不少坑才解决问题,在此记录下来,希望对大家有帮助。
首先说下使用环境:
- 代码在Linux服务器上面运行是没有问题的,可以使用ssh拉取代码。
- 本地的MacBook使用ssh可以拉取代码,但是用Java代码拉取不行。
问题解决
-
代码报错:
com.jcraft.jsch.JSchException: Algorithm negotiation fail
这个意思是说算法协商失败,SSH通信协议有一个密约和算法协商阶段,在这个阶段双方根据本端和对端支持的算法,协商出最终使用算法。不同版本的OpenSSH默认算法列表不同,可能导致了算法协商失败。 -
使用ssh -Version查看当前openssh版本
$ ssh -Version OpenSSH_7.9p1, LibreSSL 2.7.3
-
查看_rsa私钥文件头使用的协议
-----BEGIN OPENSSH PRIVATE KEY-----
-
使用
ssh-keygen -m PEM -t rsa
生成旧格式的key-----BEGIN RSA PRIVATE KEY-----
-
把新生成的ssh的public key在Gitlab仓库设置中配置
-
在 Git cloneRepository时指定ssh 私钥文件
private String private_key = "/Users/wang/.ssh/y"; SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() { @Override protected void configure(OpenSshConfig.Host host, Session session) { session.setConfig("StrictHostKeyChecking", "no"); } @Override protected JSch createDefaultJSch(FS fs) throws JSchException { JSch sch = super.createDefaultJSch(fs); sch.addIdentity(private_key); //添加私钥文件 return sch; } }; Git git = Git.cloneRepository() .setURI(gitUrl) .setTransportConfigCallback(transport -> { SshTransport sshTransport = (SshTransport) transport; sshTransport.setSshSessionFactory(sshSessionFactory); }) .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password)) .setDirectory(new File(codePath)) .setBranch(commitId) .call(); // 切换到指定commitId checkoutBranch(git, commitId); return git;
其他问题
-
JSCH连接SSH报错:Invalid privatekey
在默认使用
-----BEGIN OPENSSH PRIVATE KEY-----
协议的私钥文件时报错,使用上面的方式生成旧的rsa私钥即可。 -
在
/etc/ssh/sshd_config
文件添加下面两行,让SSH支持相应的算法和MACsKexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com,hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96
Mac上重启sshd服务
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
Mac上停止sshd服务
sudo launchctl unload -w /System/Library/LaunchDaemons/ssh.plist
如何查看进程是否启动
sudo launchctl list | grep sshd 0 com.openssh.sshd