通过JSch的SSH隧道

我的目的是连接到位于防火墙后面的服务器(主机)。我可以通过连接到网络中的另一台服务器(隧道)然后通过SSH到该服务器来访问此服务器。但是,我无法通过JSch实现相同的方案。

我无法为此编写以下代码。如果我在这里做任何愚蠢的事情,请告诉我。

public class JschExecutor {

public static void main(String[] args){

JschExecutor t=new JschExecutor();

try{

t.go();

} catch(Exception ex){

ex.printStackTrace();

}

}

public void go() throws Exception{

StringBuilder outputBuffer = new StringBuilder();

String host="xxx.xxx.xxx.xxx"; // The host to be connected finally

String user="user";

String password="passwrd";

int port=22;

String tunnelRemoteHost="xx.xx.xx.xx"; // The host from where the tunnel is created

JSch jsch=new JSch();

Session session=jsch.getSession(user, host, port);

session.setPassword(password);

localUserInfo lui=new localUserInfo();

session.setUserInfo(lui);

session.setConfig("StrictHostKeyChecking", "no");

ProxySOCKS5 proxyTunnel = new ProxySOCKS5(tunnelRemoteHost, 22);

proxyTunnel.setUserPasswd(user, password);

session.setProxy(proxyTunnel);

session.connect(30000);

Channel channel=session.openChannel("exec");

((ChannelExec)channel).setCommand("hostname");

channel.setInputStream(null);

((ChannelExec)channel).setErrStream(System.err);

InputStream in=channel.getInputStream();

BufferedReader ebr = new BufferedReader(new InputStreamReader(in));

channel.connect();

while (true) {

byte[] tmpArray=new byte[1024];

while(in.available()>0){

int i=in.read(tmpArray, 0, 1024);

if(i<0)break;

outputBuffer.append(new String(tmpArray, 0, i)).append("\n");

}

if(channel.isClosed()){

System.out.println("exit-status: "+channel.getExitStatus());

break;

}

}

ebr.close();

channel.disconnect();

session.disconnect();

System.out.println(outputBuffer.toString());

}

class localUserInfo implements UserInfo{

String passwd;

public String getPassword(){ return passwd; }

public boolean promptYesNo(String str){return true;}

public String getPassphrase(){ return null; }

public boolean promptPassphrase(String message){return true; }

public boolean promptPassword(String message){return true;}

public void showMessage(String message){}

}

}

上面的代码session.connect(30000);在行中给出了以下异常。

com.jcraft.jsch.JSchException: ProxySOCKS5: com.jcraft.jsch.JSchException: fail in SOCKS5 proxy

at com.jcraft.jsch.ProxySOCKS5.connect(ProxySOCKS5.java:317)

at com.jcraft.jsch.Session.connect(Session.java:231)

at com.ukris.main.JschExecutor.go(JschExecutor.java:50)

at com.ukris.main.JschExecutor.main(JschExecutor.java:19)

Caused by: com.jcraft.jsch.JSchException: fail in SOCKS5 proxy

at com.jcraft.jsch.ProxySOCKS5.connect(ProxySOCKS5.java:200)

... 3 more

回答:

SOCKSjsch上的代理设置允许您连接到远程端上 正在运行的 代理服务器。一个sshd在远程端将

被视为一个SOCKS代理。您需要做的是建立一个本地端口,该本地端口转发到您要隧道连接到的计算机上的ssh端口,然后使用api建立与此系统的辅助ssh连接。

我以您的示例为例,并对其进行了略微重写以实现此目的:

import com.jcraft.jsch.*;

import java.io.*;

public class JschExecutor2 {

public static void main(String[] args){

JschExecutor2 t=new JschExecutor2();

try{

t.go();

} catch(Exception ex){

ex.printStackTrace();

}

}

public void go() throws Exception{

StringBuilder outputBuffer = new StringBuilder();

String host="firstsystem"; // First level target

String user="username";

String password="firstlevelpassword";

String tunnelRemoteHost="secondlevelhost"; // The host of the second target

String secondPassword="targetsystempassword";

int port=22;

JSch jsch=new JSch();

Session session=jsch.getSession(user, host, port);

session.setPassword(password);

localUserInfo lui=new localUserInfo();

session.setUserInfo(lui);

session.setConfig("StrictHostKeyChecking", "no");

// create port from 2233 on local system to port 22 on tunnelRemoteHost

session.setPortForwardingL(2233, tunnelRemoteHost, 22);

session.connect();

session.openChannel("direct-tcpip");

// create a session connected to port 2233 on the local host.

Session secondSession = jsch.getSession(user, "localhost", 2233);

secondSession.setPassword(secondPassword);

secondSession.setUserInfo(lui);

secondSession.setConfig("StrictHostKeyChecking", "no");

secondSession.connect(); // now we're connected to the secondary system

Channel channel=secondSession.openChannel("exec");

((ChannelExec)channel).setCommand("hostname");

channel.setInputStream(null);

InputStream stdout=channel.getInputStream();

channel.connect();

while (true) {

byte[] tmpArray=new byte[1024];

while(stdout.available() > 0){

int i=stdout.read(tmpArray, 0, 1024);

if(i<0)break;

outputBuffer.append(new String(tmpArray, 0, i));

}

if(channel.isClosed()){

System.out.println("exit-status: "+channel.getExitStatus());

break;

}

}

stdout.close();

channel.disconnect();

secondSession.disconnect();

session.disconnect();

System.out.print(outputBuffer.toString());

}

class localUserInfo implements UserInfo{

String passwd;

public String getPassword(){ return passwd; }

public boolean promptYesNo(String str){return true;}

public String getPassphrase(){ return null; }

public boolean promptPassphrase(String message){return true; }

public boolean promptPassword(String message){return true;}

public void showMessage(String message){}

}

}

这段代码的作用是创建一个本地端口,将其转发到目标系统上的ssh端口,然后通过它进行连接。hostname命令的运行表明它确实在转发的系统上运行。

以上是 通过JSch的SSH隧道 的全部内容, 来源链接: utcz.com/qa/419755.html

回到顶部