JSch认证失败引发SocketTimeoutException问题排查求助
SSH认证失败时Socket客户端超时且无错误返回的问题
我有一个Socket服务,负责监听Java客户端的请求。当请求到达后,服务会通过JSch建立SSH连接到目标服务器获取信息。用户名密码正确时一切正常,但密码错误时,执行session.connect()会触发com.jcraft.jsch.JSchException: Auth fail异常,同时导致客户端与Socket服务的连接抛出SocketTimeoutException: java.net.SocketTimeoutException: Read timed out。异常发生后,代码中的out.println语句无输出,客户端无法收到错误信息。
异常信息
客户端Socket超时异常
SocketTimeoutException: java.net.SocketTimeoutException: Read timed out at java.base/java.net.SocketInputStream.socketRead0(Native Method) at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115) at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168) at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140) at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181) at java.base/java.io.BufferedReader.fill(BufferedReader.java:161) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326) at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392) at Gopher.sendCmd(Gopher.java:149) at Gopher.main(Gopher.java:110)
SSH认证失败异常
com.jcraft.jsch.JSchException: Auth fail at com.jcraft.jsch.Session.connect(Session.java:519) at com.jcraft.jsch.Session.connect(Session.java:183) at com.networkInterface.SshWorker5.doConnect3(SshWorker5.java:235) at com.simpleSw.ossgw.connectionDaemon.command.CfiCmdV3.execute(CfiCmdV3.java:2663) at com.simpleSw.ossgw.connectionDaemon.Connection.run(Connection.java:71) at com.simpleSw.ossgw.connectionDaemon.DaemonThread$ConnectionThread.run(DaemonThread.java:90) at java.base/java.lang.Thread.run(Thread.java:834)
执行流程
- Shell程序发送请求;
- Shell将请求转发给Java客户端(Gopher.java);
- 客户端从4个监听的Socket服务中选择一个发送请求;
- Socket服务接收请求,尝试通过SSH连接到请求指定的服务器;
- 执行
session.connect()时,客户端抛出SocketTimeoutException,发起请求的Shell进程终止,无法得知session.connect()内部的执行情况; - 数秒后出现Auth fail异常,但客户端已经超时,无法接收该信息。
相关代码
客户端发送请求代码
try { SocketAddress sockaddr = new InetSocketAddress(getHostName(), getPort()); NetIntSocket = new Socket(); NetIntSocket.connect(sockaddr, 5000); NetIntSocket.setSoTimeout(getTolerance()); socketOut = new PrintWriter(NetIntSocket.getOutputStream(), true); socketIn = new BufferedReader(new InputStreamReader(NetIntSocket.getInputStream())); socketOut.println(getCommand()); String line; boolean isUDC = isHLRUDC(getCommand()); while ((line = socketIn.readLine()) != null) { if (isUDC) { Pattern pattern = Pattern.compile("EPDPIND EPDPADD| NO"); Matcher matcher = pattern.matcher(line); if (!matcher.find()) System.out.println(line); } else { System.out.println(line); } } return true;
SSH连接代码
public boolean doConnect3(String sshusr, String sship, String sshpwd, String command, PrintWriter out) throws JSchException, IOException { String result=""; String result2=""; try { JSch jSch = new JSch(); session = jSch.getSession(sshusr, sship, port); session.setPassword(sshpwd); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.setTimeout(timeout); out.println("Antes session.conect timeout ["+timeout+"]"); session.connect(); // 此处触发异常 out.println("Despues session.conect timeout ["+timeout+"]"); channel = session.openChannel("shell"); channel.connect(); expect = new ExpectBuilder() .withOutput(channel.getOutputStream()) .withInputs(channel.getInputStream(), channel.getExtInputStream()) //.withEchoOutput(System.out) //.withEchoInput(System.err) .build(); // out.println("Entro al try doConnect3.expect ["+channel.isConnected()+"]"); return channel.isConnected(); } catch (JSchException e) { e.printStackTrace(); out.println("JSchException out [ "+e+" ]"); System.out.println("JSchException System.out [ "+e+" ]"); Logger.getLogger(SshWorker5.class.getName()).log(Level.SEVERE, "JSchException:", e.getMessage()); out.println("JSchException getMessage() [ "+e.getMessage()+" ]"); out.println("JSchException getCause() [ "+e.getCause()+" ]"); out.println("JSchException getStackTrace() [ "+e.getStackTrace().toString()+" ]"); return false; } catch (Exception e) { // out.println("Exception [ "+e.getMessage()+" ]"); e.printStackTrace(); Logger.getLogger(SshWorker5.class.getName()).log(Level.SEVERE, "SshConnectionException:", e); } // out.println("Entro al try doConnect3.catch ["+channel.isConnected()+"]"); return false; }
调用SSH连接的代码片段
if (sshSlave5.doConnect3(apgdata[1], apgdata[0], apgdata[2], MmlNe[0], out)) { out.println(""); out.println("<<<<< " + MmlNe[1] + " >>>>>>"); out.println(""); out.println("<" + MmlNe[0]); out.flush(); pod = sshSlave5.executeCommand(MmlNe[0], out); // out.println("Saliendo de sshSlave5.executeCommand ["+pod+"]"); sshSlave5.disconnect();; out.println(pod); doPMlog(MmlNe[1], MmlNe[0], initTime, "YES", Integer.toString(ActiveQueries), "Executed"); } else { pod = ServantData.getACCESSERRMSG(); pod = pod + "\\nOSS connectionStatus [" + qryRS + "]"; out.println(pod); out.flush(); doPMlog(MmlNe[1], MmlNe[0], initTime, "NOT", Integer.toString(ActiveQueries), "ACCESSERRMSG"); }
疑问
这是否是JSch的Bug?可能的原因是什么?
内容的提问来源于stack exchange,提问作者cblas
相关产品推荐
相关产品推荐

