
# 1.系统
cat /etc/os-release
# 系统信息
NAME="openEuler"
VERSION="22.03 (LTS-SP1)"
ID="openEuler"
VERSION_ID="22.03"
PRETTY_NAME="openEuler 22.03 (LTS-SP1)"
ANSI_COLOR="0;31"
# 2.ssh
ssh -V
# ssh信息
OpenSSH_8.8p1, OpenSSL 1.1.1m 14 Dec 2021# 1.Java报错
com.jcraft.jsch.JSchException: Algorithm negotiation fail
# 2.使用 systemctl status sshd 查看状态
Unable to negotiate with xxx.xxx.x.xxx port xxxxx: no matching host key type found.
Their offer: ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha>问题解决:
sshd_config的HostKeyAlgorithms添加算法ssh-rsaHostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-512,ssh-rsa2.问题二2.1 说明OpenSSH是从原本的OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017升级到 OpenSSH_9.7p1, OpenSSL 3.2.0 23 Nov 2023,当前环境如下:# 1.系统
CentOS Linux release 7.8.2003 (Core)
# 2.ssh -V
OpenSSH_9.7p1, OpenSSL 3.2.0 23 Nov 2023# 1.密码错误时Java报错信息
cn.hutool.extra.ssh.JschRuntimeException: JSchException: Auth fail
# 密码修改正确后 systemctl status sshd 查看状态
Accepted password for root from 123.160.246.239 port 22838 ssh2
# 2.通过sftp上传文件时
cn.hutool.extra.ssh.JschRuntimeException: JSchException: channel is not opened.
# 过一会儿后 systemctl status sshd 查看状态
error: no more sessions代码进行调试,发现报错的位置:// 报错行
channelSftp.put(fs, directory, ChannelSftp.OVERWRITE);
// 报错信息
com.jcraft.jsch.SftpException: No such file我一度认为是传输模式的问题,在ChannelSftp.put(InputStream src, String dst, int mode)方法中,mode参数用于指定文件传输模式,其可选值有:put方法时,会从上一次中断的地方继续传输,而不是重新开始传输整个文件。换用其他模式依然报错。
最终发现是代码的问题:
// 进行代码调试时发现远程登录耗时较久
SshClient.getInstance().sshRemoteCallLoginByTool(sshHost, sshPort, sshUserName, sshPassword);
// 导致创建目标目录时未执行
SshClient.getInstance().execCommandByTool("mkdir " + targetPath);execCommandByTool方法的原始代码:
/**
* 执行命令
*
* @param command 命令
*/
public String execCommandByTool(String command) {
boolean isConnected = checkConnectionStatus();
if (isConnected) {
return JschUtil.exec(session, command, Charsets.UTF_8);
}
return null;
}可以看出,如果登录较慢,checkConnectionStatus的状态是false则创建目录的命令未被执行,导致上传时的文件路径不存在,出现报错信息,改进如下:
/**
* 执行命令
*
* @param command 命令
*/
public String execCommandByTool(String command) {
boolean isConnected = checkConnectionStatus();
while (!isConnected) {
isConnected = checkConnectionStatus();
}
return JschUtil.exec(session, command, Charsets.UTF_8);
}# 连接超时异常
com.jcraft.jsch.JSchException: Session.connect: java.net.SocketTimeoutException: Read timed out
# 包损坏
com.jcraft.jsch.JSchException: Packet corrupt异常出现的位置及处理方案:
private boolean createSessionAndConnected() {
if (session == null) {
log.info("SSHClient createSessionAndConnected...");
session = JschUtil.createSession(this.sshHost, this.sshPort, this.sshUser, this.sshPass);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
try {
session.connect(8000);
// com.jcraft.jsch.JSchException: Session.connect: java.net.SocketTimeoutException: Read timed out
// 增加超时时间 session.connect(200000);
} catch (JSchException e) {
// com.jcraft.jsch.JSchException: Packet corrupt
// 使用同一个session对象再次进行连接时会报错
// 重新连接时使用新的session对象
session = null;
e.printStackTrace();
log.info("SSHClient createSessionAndConnected printStackTrace");
return false;
}
log.info("SSHClient createSessionAndConnected Success!");
}
return this.session.isConnected();
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。