SSH隧道连接两个网关通过JSch

huangapple go评论69阅读模式
英文:

SSH tunneling 2 gateways via JSch

问题

我想知道是否有可能将 https://stackoverflow.com/questions/28850188/ssh-tunneling-via-jsch 中的答案扩展到在最终主机之前有两个网关(两个中转点)的情况。

我尝试过的是:

import com.jcraft.jsch.*;
import java.io.InputStream;

public class Main {
    public static void main(String[] args){
        Main t=new Main();
        try{
            t.go();
        } catch(Exception ex){
            ex.printStackTrace();
        }
    }

    public void go() throws Exception{

        StringBuilder outputBuffer = new StringBuilder();

        String Gateway1="192.168.0.101"; // 第一级目标
        String user1="root";
        String password="12qwaszx";
        String Gateway2="192.168.0.102"; // 第二级目标的主机
        String user2 = "root";
        String secondPassword="12qwaszx";
        String endpoint = "10.81.77.52";
        String finaluser="admin";
        String finaluserpass="admin";

        JSch jsch=new JSch();
        Session session=jsch.getSession(user1, Gateway1, 22);
        session.setPassword(password);
        localUserInfo lui=new localUserInfo();
        session.setUserInfo(lui);
        session.setConfig("StrictHostKeyChecking", "no");
        // 在本地系统上从端口2233创建到tunnelRemoteHost上的端口22的端口
        session.setPortForwardingL(2233, Gateway2, 22);
        session.connect();
        session.openChannel("direct-tcpip");

        // 创建连接到本地主机上端口2233的会话。
        Session secondSession = jsch.getSession(user2, "localhost", 2233);
        secondSession.setPassword(secondPassword);
        secondSession.setUserInfo(lui);
        secondSession.setConfig("StrictHostKeyChecking", "no");
        secondSession.setPortForwardingL(2233, endpoint, 22);
        secondSession.connect(); // 现在我们连接到了次级系统
        secondSession.openChannel("direct-tcpip");

        Session finalSession = jsch.getSession(finaluser, "localhost", 2233);
        finalSession.setPassword(finaluserpass);
        finalSession.setUserInfo(lui);
        finalSession.setConfig("StrictHostKeyChecking", "no");
        finalSession.connect();

        Channel channel=secondSession.openChannel("exec");
        ((ChannelExec)channel).setCommand("show system information | match \"System Name\"");

        channel.setInputStream(null);

        InputStream stdout=channel.getInputStream();

        channel.connect();
        if (channel.isConnected()){
            System.out.println("connected");
        }

        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){}
    }
}

但是尽管我努力了,我实际上并没有连接到终端点。得到了以下错误信息:

com.jcraft.jsch.JSchException: PortForwardingL: local port 127.0.0.1:2233 cannot be bound.
at com.jcraft.jsch.PortWatcher.<init>(PortWatcher.java:158)
at com.jcraft.jsch.PortWatcher.addPort(PortWatcher.java:110)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1847)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1828)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1809)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1792)
at Main.go(Main.java:36)
at Main.main(Main.java:9)
Caused by: java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at com.jcraft.jsch.PortWatcher.<init>(PortWatcher.java:150)
... 7 more
Process finished with exit code 0

如果有人能够帮助我,我将不胜感激。我需要通过 SSH 隧道连接两个网关到终端点。

英文:

I wonder if its possible to extend the answer in https://stackoverflow.com/questions/28850188/ssh-tunneling-via-jsch to a case where I have two gateways (two points) before the final host.

What I tried was

import com.jcraft.jsch.*;
import java.io.InputStream;
public class Main {
public static void main(String[] args){
Main t=new Main();
try{
t.go();
} catch(Exception ex){
ex.printStackTrace();
}
}
public void go() throws Exception{
StringBuilder outputBuffer = new StringBuilder();
String Gateway1=&quot;192.168.0.101&quot;; // First level target
String user1=&quot;root&quot;;
String password=&quot;12qwaszx&quot;;
String Gateway2=&quot;192.168.0.102&quot;; // The host of the second target
String user2 = &quot;root&quot;;
String secondPassword=&quot;12qwaszx&quot;;
String endpoint = &quot;10.81.77.52&quot;;
String finaluser=&quot;admin&quot;;
String finaluserpass=&quot;admin&quot;;
JSch jsch=new JSch();
Session session=jsch.getSession(user1, Gateway1, 22);
session.setPassword(password);
localUserInfo lui=new localUserInfo();
session.setUserInfo(lui);
session.setConfig(&quot;StrictHostKeyChecking&quot;, &quot;no&quot;);
// create port from 2233 on local system to port 22 on tunnelRemoteHost
session.setPortForwardingL(2233, Gateway2, 22);
session.connect();
session.openChannel(&quot;direct-tcpip&quot;);
// create a session connected to port 2233 on the local host.
Session secondSession = jsch.getSession(user2, &quot;localhost&quot;, 2233);
secondSession.setPassword(secondPassword);
secondSession.setUserInfo(lui);
secondSession.setConfig(&quot;StrictHostKeyChecking&quot;, &quot;no&quot;);
secondSession.setPortForwardingL(2233, endpoint, 22);
secondSession.connect(); // now we&#39;re connected to the secondary system
secondSession.openChannel(&quot;direct-tcpip&quot;);
Session finalSession = jsch.getSession(finaluser, &quot;localhost&quot;, 2233);
finalSession.setPassword(finaluserpass);
finalSession.setUserInfo(lui);
finalSession.setConfig(&quot;StrictHostKeyChecking&quot;, &quot;no&quot;);
finalSession.connect();
Channel channel=secondSession.openChannel(&quot;exec&quot;);
((ChannelExec)channel).setCommand(&quot;show system information | match \&quot;System Name\&quot;&quot;);
channel.setInputStream(null);
InputStream stdout=channel.getInputStream();
channel.connect();
if (channel.isConnected()){
System.out.println(&quot;connected&quot;);
}
while (true) {
byte[] tmpArray=new byte[1024];
while(stdout.available() &gt; 0){
int i=stdout.read(tmpArray, 0, 1024);
if(i&lt;0)break;
outputBuffer.append(new String(tmpArray, 0, i));
}
if(channel.isClosed()){
System.out.println(&quot;exit-status: &quot;+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){}
}
}

But despite my efforts, I don't actually get to connect to the endpoint. Getting

com.jcraft.jsch.JSchException: PortForwardingL: local port 127.0.0.1:2233 cannot be bound.
at com.jcraft.jsch.PortWatcher.&lt;init&gt;(PortWatcher.java:158)
at com.jcraft.jsch.PortWatcher.addPort(PortWatcher.java:110)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1847)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1828)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1809)
at com.jcraft.jsch.Session.setPortForwardingL(Session.java:1792)
at Main.go(Main.java:36)
at Main.main(Main.java:9)
Caused by: java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.&lt;init&gt;(ServerSocket.java:237)
at com.jcraft.jsch.PortWatcher.&lt;init&gt;(PortWatcher.java:150)
... 7 more
Process finished with exit code 0

Please, if anyone could help me. I need to Get to the endpoint by ssh tunneling two gateways.

答案1

得分: 0

我发誓我不是故意的,

但问题是第一个本地端口等于第二个。

它的工作原理如下:

  session.setPortForwardingL(2222, Gateway2, 22);
session.connect();
session.openChannel("direct-tcpip");
Session secondSession = jsch.getSession(user2, "localhost", 2222);
英文:

I swear I didn't meant it,

but the problem was that the first lport was equal to the second.

it worked like bellow:

  session.setPortForwardingL(2222, Gateway2, 22);
session.connect();
session.openChannel(&quot;direct-tcpip&quot;);
Session secondSession = jsch.getSession(user2, &quot;localhost&quot;, 2222);

huangapple
  • 本文由 发表于 2020年5月30日 10:37:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/62097141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定