问题:jsch-0.1.53.jar通过sftp远程连接ssh8.7版本的linux服务器报错Exception:Algorithm negotiation fail解决方案
时间:2022年05月13日 晚8点
问题描述:
正式服A环境部署的服务后台程序中,有一个功能是通过jsch.jar包的中的方法实现通过账号密码sftp远程连接另一台服务器B,并进行文件传输。
由于连接配置这一块基本没动过,之前一直是正常的(能够连接成功,正常传输文件)。今天由于应标需要,得准备上报隐患功能的视频录制,系统点击提交一直不成功。检查后台日志,发现报这个错误:
解决方法:
先是分析报错的日志信息,现象是程序通过sftp远程连接失败
然后排查B服务器是否正常,端口是否开放
确认B服务器正常,且端口开放后,通过正式服A检测端口:
Telnet ok
在A服务器终端通过sftp命令远程连接:
Sftp命令连接 ok
再通过系统,点击上报,还是失败,依旧报之前的错
得出结论:A服务器终端通过sftp命令可以连接成功,但是通过程序进行sftp连接就失败了。
查阅网上关于 Exception message is: Algorithm negotiation fail 报错的解答
大致意思是:报错原因是算法协商失败。具体呢,就是我们程序中的jsch包提供远程连接另一台服务器,会涉及到加密算法这个概念。sftp和ssh的加密算法是差不多的。
简单理解就是一台linux服务器,它会有个ssh的服务,不同版本的ssh会支持不同的加密算法,用于远程连接时的身份认证,主要为了加固连接隧道的安全性,避免窃听,连接劫持等攻击。那么我们程序的jsch包中提供的连接方法,就需要去支持指定ssh版本所使用的加密算法。保持一致后才能连接成功。
那么基本能确定,这个报错肯定跟ssh版本有那么几分关系了。然后我去咨询了网管部门的相关人员,沟通后得知,他们确实对服务器B进行了ssh的升级,主要是集团的网络安全要求,所有组件升级到最新稳定版本,避免安全漏洞。
因为服务器B使用的是ssh8.7版本,应该算是比较新的了
而且网上资料说8.7版本的ssh停用了一些旧的签名算法,然后我就推测可能是我们系统程序包中jsch.jar包的版本不能覆盖最新的ssh支持的加密算法,导致认证未通过,连接失败。
去maven官网仓库中查找到jsch的最新版本为0.1.55
我们程序里用的是0.1.53版本。
由于情况紧急,时间仓促,只能抱着试一试的心态去验证自己的猜想。于是在晚上11点多,打电话跟领导提了申请,备份了生产库上的程序包。自己在本地拉取了分支版本的源码,修改了jsch版本,改成了0.1.55版本。然后打包,加密,部署到生产库上。再打开日志监控,联系同事进行功能测试,TMD,通了..
这个问题最终解决方案就是:升级程序中的jsch.jar包,改成更高的版本,就行了
真实企业工作中,不建议大家直接在生产环境中这样处理。一般需要在测试服上还原线上的故障场景,通过网上提供的,以及自己思考的方法去一步步验证,直到找出报错的准确原因,并能够在测试服上解决故障。然后向领导报备,才去生产服上修改。
但是我们这个问题,必须在一天内解决,时间紧迫。而且生产服务器是远程的,我们这边基本维护都是通过远程ssh或sftp访问的。而且正式服A和服务器B都是在一个特殊的局域网环境下。我们无法在测试服中比较真实的模拟线上环境。我只能找一种最快,最有效,对生产影响最小的方案去验证,并解决问题。
由于自己对运维这块技术摸得较浅。排查问题的期间,跟合作方技术人员,找同事,同事的做运维的同学一起沟通,一起分析。可能很多生产中细小的问题,很少人会遇到,但是分析,思考,验证,决策的过程都是一笔宝贵的财富。摸索的过程中,会慢慢积累经验。
记录一下吧,难得碰到一个之前没见过,有点棘手的问题,而且耗费很长时间才解决了。