You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JSch中无需认证获取服务器SSH版本?

如何在Java中无需认证获取SSH服务器版本?

我尝试用JSch编写了如下测试代码:

@Test
public void test() throws Exception {
    var session = new JSch().getSession("host");
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    var version = session.getServerVersion();
    System.out.println("version = " + version);
}

运行时抛出异常:

java.lang.NullPointerException: Cannot read the array length because "str" is null

看起来JSch需要连接并完成认证才能调用getServerVersion()。想请教下Java里怎么不用认证就能获取SSH服务器版本?

另外我用Python的Paramiko可以实现无需认证获取版本,代码如下:

import paramiko

ssh = paramiko.Transport(("host", 22))
ssh.start_client()
print(ssh.remote_version)
ssh.close()

要在JSch中无需认证获取SSH服务器版本,你需要先建立底层TCP连接并完成SSH初始握手,但不需要执行认证步骤。JSch的Session对象在调用connect()方法时,会先完成握手流程(此时服务器已经发送了版本信息),即便没有提供认证凭据,也能拿到版本号——绝大多数SSH服务器都会允许完成这个初始握手环节。

修改后的可行代码如下:

@Test
public void testSshVersion() throws Exception {
    JSch jsch = new JSch();
    Session session = jsch.getSession("host", 22); // 显式指定端口,默认也是22
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    
    try {
        // 调用connect完成初始握手,设置超时避免无限等待
        session.connect(3000);
        String serverVersion = session.getServerVersion();
        System.out.println("SSH服务器版本: " + serverVersion);
    } catch (JSchException e) {
        // 会抛出认证失败异常,但握手已完成,版本信息已被JSch存储
        String serverVersion = session.getServerVersion();
        if (serverVersion != null) {
            System.out.println("SSH服务器版本: " + serverVersion);
        } else {
            e.printStackTrace();
        }
    } finally {
        if (session.isConnected()) {
            session.disconnect();
        }
    }
}

原理说明:

SSH协议的核心流程是:

  1. 建立TCP连接
  2. 服务器主动发送版本字符串(如SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.9)
  3. 客户端发送自身版本字符串
  4. 进入密钥交换与认证环节

JSch的connect()方法会执行完前3步后才触发认证,所以即便认证失败,服务器的版本信息已经被接收并存储,此时调用getServerVersion()就能拿到结果。这和你用Paramiko时调用start_client()的逻辑完全一致——都是只完成初始握手,不执行认证。

内容的提问来源于stack exchange,提问作者greenButMellow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:12:46