ch.ethz.ssh2报错java.io.IOException: Key exchange was not finished, connection is closed.

文章描述了在使用ch.ethz.ssh2库连接远程服务器时遇到的KeyExchange未完成错误,通常的解决方案是修改sshd_config文件中的KexAlgorithms、HostKeyAlgorithms和MACs参数。然而,作者指出这可能并不总是有效,需要检查客户端和服务器之间的算法匹配。通过分析ch.ethz.ssh2的源码,发现需要确保服务端配置包含客户端支持的算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ch.ethz.ssh2连接远程服务器的时候报错:

java.io.IOException: Key exchange was not finished, connection is closed.
at ch.ethz.ssh2.transport.KexManager.getOrWaitForConnectionInfo(KexManager.java:75)
at ch.ethz.ssh2.transport.TransportManager.getConnectionInfo(TransportManager.java:169)
at ch.ethz.ssh2.Connection.connect(Connection.java:759)
at ch.ethz.ssh2.Connection.connect(Connection.java:628)
at com.act.datasmart.operators.utils.RemoteShellUtil.login(RemoteShellUtil.java:33)
at com.act.datasmart.operators.RemoteShellOperator.action(RemoteShellOperator.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
...
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:955)
at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:203)
at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:90)
at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:1043)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:1052)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.io.IOException: Cannot negotiate, proposals do not match.
at ch.ethz.ssh2.transport.ClientKexManager.handleMessage(ClientKexManager.java:123)
at ch.ethz.ssh2.transport.TransportManager.receiveLoop(TransportManager.java:572)
at ch.ethz.ssh2.transport.TransportManager$1.run(TransportManager.java:261)
at java.lang.Thread.run(Thread.java:748)

看到很多文章都是执行以下三步:
1、修改配置文件

vim /etc/ssh/sshd_config

2、修改KexAlgorithms参数

KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group1-sha1,curve25519-sha256@libssh.org

3、重启服务

service sshd restart

但是实测发现KexAlgorithms只是其中一种原因,不一定能解决各位的问题,现在跟着代码看是哪些原因导致。

1、找到ch.ethz.ssh2.transport.KexManager类,其中有个方法mergeKexParameters,这个就是匹配服务端客户端两边相关参数通用的算法,底层调用getFirstMatch去比较二者相同的算法。
定位到以下三个地方
在这里插入图片描述

其中kex_algo比较的是KexAlgorithms参数的值,定位到其init方法,发现ch.ethz.ssh2默认支持的kex算法是"diffie-hellman-group-exchange-sha1", “diffie-hellman-group14-sha1”, “diffie-hellman-group1-sha1”,所以sshd_config里KexAlgorithms参数需要有其中之一。

在这里插入图片描述在这里插入图片描述同理,定位到HostKeyAlgorithms默认支持"ssh-rsa",“ssh-dss”,
可在sshd_config里加上
HostKeyAlgorithms +ssh-dss,ssh-rsa
mac_algorithms_client_to_server默认值为"hmac-sha1-96”, “hmac-sha1”, “hmac-md5-96”, "hmac-md5”,
所以sshd_config里MACs参数至少得包含其中一种

### 解决 `connection is closed` 错误的方法 #### Java 连接 Linux 服务器中的密钥交换未完成问题 当尝试通过Java连接到Linux服务器并收到错误消息“Key exchange was not finished, connection is closed.”时,通常是因为SSH客户端未能成功与远程主机建立安全会话。此情况可能由多种因素引起,包括但不限于防火墙设置、SSH配置文件不当或是网络不稳定等问题[^1]。 为了处理这种情况,在应用程序层面可以考虑增加重试机制来应对临时性的网络波动;另外检查本地及远端机器上的SSH服务版本兼容性和安全性参数匹配度也非常重要。如果是在开发环境中,则建议简化环境变量直至最小化差异以便快速定位具体成因。 #### Spring Boot 应用中 MySQL 空闲超时断开连接的情况 针对Spring Boot应用访问MySQL数据库过程中发生的“Connection is closed”异常,主要源于长时间闲置后的自动断线行为或者是由于执行了一个非法操作而触发了这种状态变化。尽管存在连接池组件负责维持活动链接的有效性,但如果这些持久化的TCP/IP套接字处于非活跃状态下超过一定时限就会被强制终止[^2]。 对此类情形的一个常见对策就是在数据源属性里调整心跳检测间隔时间以及最大等待秒数等选项,确保即使在网络状况不佳的情况下也能保持足够的存活探测频率从而预防意外掉线的发生。同时也可以启用懒加载模式减少不必要的资源占用,并且合理规划事务边界避免跨多个请求共享同一个物理连接实例。 #### 调整JDBC连接释放逻辑防止意外关闭 在某些情况下,程序内部对于数据库连接对象的操作失误也会造成类似的故障表现形式——即试图在一个已经被标记为已关闭的状态上调用了方法调用链路里的其他成员函数。例如提供的代码片段展示了如何优雅地回收不再使用的Session句柄,但是如果没有正确同步多线程间的协作关系或者忽视了潜在并发冲突的话仍然有可能引发上述提及的现象[^4]。 因此应当仔细审查涉及数据库交互部分的业务流程设计文档,确认所有必要的清理工作都已经妥善安排到位。特别是要注意区分正常结束生命周期的情形同突发中断事件之间的区别对待方式,前者可以通过标准API接口实现平滑过渡,后者则需额外加入补偿措施以保障系统的整体稳定性。 ```java // 正确的方式应该先判断是否为空再做进一步动作 if (con != null && !con.isClosed()) { con.close(); } ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值