java ssh连接,使用Java的SSH连接

I am trying to establish an SSH connection through my Java code, but getting below exception .. I tested my connection through Putty/Winscp tools and it works fine. The problem is with my Java code...

SEVERE: The Transport Protocol thread failed

java.io.IOException: The socket is EOF

at com.sshtools.j2ssh.transport.TransportProtocolInputStream.readBufferedData(Unknown Source)

at com.sshtools.j2ssh.transport.TransportProtocolInputStream.readMessage(Unknown Source)

at com.sshtools.j2ssh.transport.TransportProtocolCommon.readMessage(Unknown Source)

at com.sshtools.j2ssh.transport.kex.DhGroup1Sha1.performClientExchange(Unknown Source)

at com.sshtools.j2ssh.transport.TransportProtocolClient.performKeyExchange(Unknown Source)

at com.sshtools.j2ssh.transport.TransportProtocolCommon.beginKeyExchange(Unknown Source)

at com.sshtools.j2ssh.transport.TransportProtocolCommon.onMsgKexInit(Unknown Source)

at com.sshtools.j2ssh.transport.TransportProtocolCommon.startBinaryPacketProtocol(Unknown Source)

at com.sshtools.j2ssh.transport.TransportProtocolCommon.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

Below is my piece of Java code to establish the connection

public class MySSHClient {

static SshClient ssh = null;

static SshConnectionProperties properties = null;

SessionChannelClient session = null;

private static void MySSHClient(String hostName, String userName, String passwd )

{

try

{

// Make a client connection

ssh = new SshClient();

properties = new SshConnectionProperties();

properties.setHost("192.168.1.175");

// Connect to the host

ssh.connect(properties, new IgnoreHostKeyVerification());

// Create a password authentication instance

PasswordAuthenticationClient pwd = new PasswordAuthenticationClient();

pwd.setUsername("root");

pwd.setPassword("123456");

// Try the authentication

int result = ssh.authenticate(pwd);

// Evaluate the result

if (result==AuthenticationProtocolState.COMPLETE) {

System.out.println("Connection Authenticated");

}

}

catch(Exception e)

{

System.out.println("Exception : " + e.getMessage());

}

}//end of method.

public String execCmd(String cmd)

{

String theOutput = "";

try

{

// The connection is authenticated we can now do some real work!

session = ssh.openSessionChannel();

if ( session.executeCommand(cmd) )

{

IOStreamConnector output = new IOStreamConnector();

java.io.ByteArrayOutputStream bos = new

java.io.ByteArrayOutputStream();

output.connect(session.getInputStream(), bos );

session.getState().waitForState(ChannelState.CHANNEL_CLOSED);

theOutput = bos.toString();

}

//else

//throw Exception("Failed to execute command : " + cmd);

//System.out.println("Failed to execute command : " + cmd);

}

catch(Exception e)

{

System.out.println("Exception : " + e.getMessage());

}

return theOutput;

}

public static void main(String[] args){

MySSHClient(null, null, null);

}

解决方案

Motivation

I stumbled across this question and answers while investigating the error in question java.io.IOException: The socket is EOF. Because changing the code to use some other SSH Java library is not immediately possible in my case and the stated explanation by @a3.14_Infinity was not detailed enough for me, I'd like to add my take on it.

java.io.IOException: The socket is EOF - Why?

Because this exception is not very helpful, I first tried Wireshark to see what's going on over the wire, but to no avail. So I configured the sshd_config (OpenSSH 6.9) to log on DEBUG3 level and got the answer in the /var/log/auth.log file of my test machine. It stated a fatal error while trying to negotiate the key exchange algorithm with the SSH client (the Java SSH library).

Because the SSH server and client could not agree on a mutual key exchange algorithm the OpenSSH server terminates the connection to the client. In consequence, the Java SSH library code throws the exception.

But why does it happen?

The sshtools.j2ssh (sshtools : j2ssh-core : 0.2.9) library code is pretty old and discontinued. Starting with OpenSSH 6.7 (released October, 2014) default ciphers and MAC have been altered to remove unsafe algorithms which includes the blowfish-cbc cipher. And with OpenSSH 6.9 (released June, 2015) the support for the 1024-bit diffie-hellman-group1-sha1 key exchange is disabled by default.

When you still use the prehistoric SSH Tools j2ssh library (God forbid) connecting to a newer OpenSSH server you will get the described error. The library code only offers the diffie-hellman-group1-sha1 key exchange algorithm to the OpenSSH server which it does not support by default. Thus, a secure connection cannot be established.

Cannot change the code?

If moving to another Java SSH library is not immediately possible (my case) then you can re-enable the disabled diffie-hellman-group1-sha1 key exchange algorithm in the OpenSSH's server config file sshd_config. For example like this.

Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,blowfish-cbc

KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1

But let me be clear on this. The diffie-hellman-group1-sha1 key exchange algorithm as well as the blowfish-cbc cipher are turned off by default because they are insecure. Reenabling them should only be a temporary measure until you can replace this obsolete Java SSH library.

Finally, I like to point out that the suggested Java Secure Channel (JSch) library in other answers is discontinued. So, you might want to consider sshj or even ssh2j-maverick instead.

Edit: I was wrong, the Java Secure Channel JSch library is alive (JSCH 0.1.54 was released on 2016-09-03 on MavenCentral) and certainly worth your consideration. Alternatively, you may want to consider also sshj or ssh2j-maverick.

Addendum: Migration

To keep the migration effort for the sshtools.j2ssh (sshtools : j2ssh-core : 0.2.9) library minimal I looked at the commercial legacy SSH client library from SSHTOOLS (version 1.7.1). This allowed to keep the existing library integration code with few minor changes regarding library API and exception handling. Thus, if you do not want to restart from scratch then biting the bullet and sticking with SSHTOOLS is probably your best option. Finally, to gauge the migration effort I first replaced the library with SSHTOOLS' open source library ssh2j-maverick which almost has the same API as its latest commercial version (version 1.7.1).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值