现象

最近把Jenkins从2.401.3升级至2.428后(严格来说,是JSch插件从0.1.x升级到了0.2.x后),原先能正常工作的部分Pipeline无法执行,报错信息为:

com.jcraft.jsch.JSchAlgoNegoFailException: Algorithm negotiation fail: algorithmName="server_host_key" jschProposal="ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256" serverProposal="ssh-rsa,ssh-dss"

原因分析

错误信息的大意是客户端和服务端使用的算法无法兼容,其中 jschProposal 是我们的Jenkins SSH插件启用的算法列表,而 serverProposal 是服务端支持的算法列表。

出现这种情况,多半是ssh服务端版本太低,算法过时(比如 CentOS / RedHat 6 自带的 sshd),而新版本的Jenkins的 JSch dependency plugin 0.2.x 默认禁用了这些算法,参考 JSch v0.2.0 的 Release:Release v0.2.0 · mwiede/jsch (github.com)icon-default.png?t=N7T8https://github.com/mwiede/jsch/releases/tag/jsch-0.2.0

解决

JSch官方也提出了几个兼容老系统的方案,参考:mwiede/jsch: fork of the popular jsch library (github.com)icon-default.png?t=N7T8https://github.com/mwiede/jsch#why-do-ssh-rsa-type-keys-not-work-with-this-jsch-fork-and-my-server

这里放一个验证过可行的方案,就是让 JSch 支持 ssh-rsa(ssh-dss同理):

修改jenkins启动命令,添加系统属性 -Djsch.client_pubkey 和 -Djsch.server_host_key,JSch运行时会读取该属性,覆盖默认配置。

这两个属性的值实际上就是把报错信息里的 jschProposal 拿过来,在后面追加一个 ssh-rsa。

java -jar \
-Djsch.client_pubkey=ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa \
-Djsch.server_host_key=ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa \
jenkins-2.428.war --prefix=/jenkins

结语

这次发生问题的Jenkins插件版本比较新,还算热乎,暂时也没有搜到相关中文资料,所以分享出来。

也试过官方提到的其他方案,比如调整Jenkins所在服务器的 /etc/ssh/ssh_config~/.ssh/config 等配置文件,根本没有效果,可能是因为Jenkins里的JSch是经过 SSH Pipeline Steps 插件封装调用的,没有读取这些配置(当然也不排除是我调整的姿势不对)。

Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐