【问题标题】:Java JSch SSH tunneling send HTTP or HTTPs requests to remote serverJava JSch SSH 隧道向远程服务器发送 HTTP 或 HTTPS 请求
【发布时间】:2014-07-09 05:01:45
【问题描述】:

Java 程序员们。我一直面临着使用 SSH 连接到服务器从另一台服务器加载网页的任务。很快我发现我对网络协议的了解非常有限。首先,我尝试了动态端口转发 - 无济于事,它仅在商业图书馆中可用(而且所有这些都远远超出了我的经济能力)。然后我了解到,使用 JSch,您实际上可以创建一个称为直接 tcp-IP 通道的东西(我仍在尝试掌握这个概念),并且我在 stackoverflow 上找到了一些代码,应该使用它来发送 HTTP通过 SSH 连接到使用 JSch 的另一台服务器向远程服务器发出请求。这是代码(在TCP Connection over a secure ssh connection的原始版本中略有修改)

    String host = "66.104.230.49";
    String user = "admin";
    String password = "default";
    int port = 22;

    String remoteHost = "souzpp.ru";
    int remotePort = 80;

    int localPort = 5001;
    int assignedPort;
    String localHost = "127.0.0.1";

    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");

    try { 
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, port);
        session.setPassword(password);
        session.setConfig(config);
        session.connect();
        assignedPort = session.setPortForwardingL(localPort, remoteHost, remotePort);
        Channel channel = session.openChannel("direct-tcpip");  

        System.out.println(assignedPort);
        ((ChannelDirectTCPIP)channel).setHost(localHost);
        ((ChannelDirectTCPIP)channel).setPort(assignedPort);

        String cmd = "GET /files/inst HTTP/1.0\r\n\r\n";

        InputStream in = channel.getInputStream();
        OutputStream out = channel.getOutputStream();

        channel.connect(10000);

        byte[] bytes = cmd.getBytes();          
        InputStream is = new ByteArrayInputStream(cmd.getBytes("UTF-8"));

        int numRead;

        while ((numRead = is.read(bytes)) >= 0)
              out.write(bytes, 0, numRead);

        out.flush();
        channel.disconnect();
        session.disconnect();

        System.out.println("Request supposed to have been sent");

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            for (String line; (line = reader.readLine()) != null;){
                System.out.println(line);
            }
        } catch (java.io.IOException exc) {
            System.out.println(exc.toString());
        }

    } catch (Exception e){
        e.printStackTrace();
    }

此代码引发以下异常:com.jcraft.jsch.JSchException:通道未打开。 这里可能有什么问题?拜托,如果答案与网络逻辑中的错误有关,而不是与实施中的错误有关,如果您给我一个链接,其中包含有关我所犯错误的有用信息,我将非常高兴。

(编辑:按照 JavaCoderEx 的建议添加了端口转发)

【问题讨论】:

    标签: java http ssh jsch tcp-ip


    【解决方案1】:

    您可以选择先设置 SSH 隧道吗?

    我创建了一个脚本,其中包含: sudo ssh -i /Users/myuser/.ssh/id_rsa -2 -f -N myuser@remotehost -L 8080/127.0.0.1/80

    上面的代码创建了一个反向 SSH 隧道,从 8080 上的 localhost 发出的请求通过隧道,最终成为另一端 80 上的请求。现在您可以创建一个流来响应用户请求并打开一个流(url 连接)到另一个服务器 - 本质上您现在正在创建一个代理。

    【讨论】:

    • 为什么要使用反向 SSH 隧道?根据我对 SSH 隧道/端口转发的理解,我需要的不是本地端口转发(不是远程/反向)吗?附言我已经用本地端口转发更新了我的代码,但它仍然不起作用,请看看它
    • 如果您在 localhost 的命令行上 - 发出 SSH 命令打开隧道,然后使用 wget 或 curl 之类的东西 - 它有效吗?如果是底层 ssh 连接导致问题,我只关心对代码中的某些内容进行故障排除。
    【解决方案2】:
    InputStream in = channel.getInputStream();
    [...]
    channel.disconnect();
    session.disconnect();
    [...]
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    for (String line; (line = reader.readLine()) != null;){
    

    您正在关闭 TCP 流通道,然后关闭整个 SSH 会话,然后尝试从通道中读取。

    在真正完成之前不要关闭 SSH 会话或通道。

    【讨论】:

      猜你喜欢
      • 2018-10-04
      • 1970-01-01
      • 2015-07-28
      • 2013-05-04
      • 1970-01-01
      • 2020-07-15
      • 1970-01-01
      • 2015-03-09
      • 2012-12-12
      相关资源
      最近更新 更多