ganymed-ssh2连接openssh 8.2
存在的问题
ganymed-ssh2是一个ssh-2协议实现,因为该项目比较老旧,当sshd服务使用较新的openssh时,一般情况下是无法正常建立ssh连接的。
访问sshd的代码,如下所示:
java
public class Main {
public static void main(String[] args) throws IOException {
String ipAddress = "127.0.0.1";
ch.ethz.ssh2.Connection conn = new ch.ethz.ssh2.Connection(ipAddress,22);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword("username", "password");
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
}
}
当使用如下代码访问sshd时,系统会报如下异常:
解决方法
找到报错代码
下载ganymed-ssh2源码,源码地址为https://www.ganymed.ethz.ch/ssh2/。
找到ch.ethz.ssh2.transport.KexManager文件,搜索异常关键字"Cannot negotiate, proposals do not match."。代码如下所示:
java
kxs.np = mergeKexParameters(kxs.localKEX.getKexParameters(), kxs.remoteKEX.getKexParameters());
if (kxs.np == null)
throw new IOException("Cannot negotiate, proposals do not match.");
从中可知,mergeKexParameters方法返回的kxs.np为空,导致报上述异常。进入mergeKexParameters方法,发现异常原因是因为getFirstMatch方法返回NegotiateException。
打印客户端和服务端协商的算法过程
java
private String getFirstMatch(String[] client, String[] server) throws NegotiateException
{
if (client == null || server == null)
throw new IllegalArgumentException();
if (client.length == 0)
return null;
log.log(20, "------------------------------");
for (int i = 0; i < client.length; i++)
{
log.log(20, "client-->" + client[i]);
for (int j = 0; j < server.length; j++)
{
log.log(20, "server-->" + server[i]);
if (client[i].equals(server[j]))
return client[i];
}
}
log.log(20, "------------------------------");
throw new NegotiateException();
}
shell
1750672202863 : ch.ethz.ssh2.transport.TransportConnection: Sent SSH_MSG_KEXINIT 478 bytes payload
1750672202864 : ch.ethz.ssh2.transport.TransportConnection: Received SSH_MSG_KEXINIT 929 bytes payload
1750672202868 : ch.ethz.ssh2.transport.KexManager: ------------------------------
1750672202868 : ch.ethz.ssh2.transport.KexManager: client-->diffie-hellman-group-exchange-sha1
1750672202868 : ch.ethz.ssh2.transport.KexManager: server-->curve25519-sha256
1750672202868 : ch.ethz.ssh2.transport.KexManager: server-->curve25519-sha256
1750672202868 : ch.ethz.ssh2.transport.KexManager: server-->curve25519-sha256
1750672202868 : ch.ethz.ssh2.transport.KexManager: server-->curve25519-sha256
1750672202868 : ch.ethz.ssh2.transport.KexManager: server-->curve25519-sha256
1750672202868 : ch.ethz.ssh2.transport.KexManager: kex_algo=diffie-hellman-group-exchange-sha1
1750672202868 : ch.ethz.ssh2.transport.KexManager: ------------------------------
1750672202868 : ch.ethz.ssh2.transport.KexManager: client-->ssh-rsa
1750672202868 : ch.ethz.ssh2.transport.KexManager: server-->rsa-sha2-512
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->rsa-sha2-512
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->rsa-sha2-512
1750672202869 : ch.ethz.ssh2.transport.KexManager: server_host_key_algo=ssh-rsa
1750672202869 : ch.ethz.ssh2.transport.KexManager: ------------------------------
1750672202869 : ch.ethz.ssh2.transport.KexManager: client-->aes256-ctr
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: ------------------------------
1750672202869 : ch.ethz.ssh2.transport.KexManager: client-->aes256-ctr
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->3des-cbc
1750672202869 : ch.ethz.ssh2.transport.KexManager: enc_algo_client_to_server=aes256-ctr
1750672202869 : ch.ethz.ssh2.transport.KexManager: enc_algo_server_to_client=aes256-ctr
1750672202869 : ch.ethz.ssh2.transport.KexManager: ------------------------------
1750672202869 : ch.ethz.ssh2.transport.KexManager: client-->hmac-sha1-96
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512
1750672202869 : ch.ethz.ssh2.transport.KexManager: client-->hmac-sha1
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512-etm@openssh.com
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512-etm@openssh.com
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512-etm@openssh.com
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-512-etm@openssh.com
1750672202869 : ch.ethz.ssh2.transport.KexManager: client-->hmac-md5-96
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256
1750672202869 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256
1750672202870 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256
1750672202870 : ch.ethz.ssh2.transport.KexManager: client-->hmac-md5
1750672202870 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256-etm@openssh.com
1750672202870 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256-etm@openssh.com
1750672202870 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256-etm@openssh.com
1750672202870 : ch.ethz.ssh2.transport.KexManager: server-->hmac-sha2-256-etm@openssh.com
1750672202870 : ch.ethz.ssh2.transport.KexManager: ------------------------------
1750672202870 : ch.ethz.ssh2.transport.TransportManager: Receive thread: error in receiveLoop: Cannot negotiate, proposals do not match.
1750672202870 : ch.ethz.ssh2.transport.TransportManager: Receive thread: back from receiveLoop
从日志可知,客户端支持的算法有:hmac-sha1-96,hmac-sha1,hmac-md5-96,hmac-md5四种;服务端支持的算法有:hmac-sha2-512,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-256-etm@openssh.com四种。客户端和服务端没有共同的算法。
查看服务器/etc/ssh/sshd_config文件,可知,hmac算法配置在MACs项中。 修改sshd_config,新增算法hmac-sha1-96,hmac-sha1,hmac-md5-96,hmac-md5,然后重启sshd服务。
测试ssh连接
略
idea编译ganymed-ssh2
解压下载的源码
unzip ganymed-ssh2-build210.zip -d ganymed
添加pom.xml配置
ganymed-ssh2是一个普通的java工程,不方便编译和打包测试,将其转换为maven项目。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.ethz.ssh2</groupId>
<artifactId>test-ganymed</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>ch.ethz.ssh2.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
导入idea
在idea中鼠标右键选中pom.xml, 点击"Add as Maven Project"。此时,ganymed项目可以在idea下,通过maven插件进行编译和打包。