如何在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协议的核心流程是:
- 建立TCP连接
- 服务器主动发送版本字符串(如
SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.9) - 客户端发送自身版本字符串
- 进入密钥交换与认证环节
JSch的connect()方法会执行完前3步后才触发认证,所以即便认证失败,服务器的版本信息已经被接收并存储,此时调用getServerVersion()就能拿到结果。这和你用Paramiko时调用start_client()的逻辑完全一致——都是只完成初始握手,不执行认证。
内容的提问来源于stack exchange,提问作者greenButMellow
相关产品推荐
相关产品推荐

