Java JSch SSH隧道将HTTP或HTTPs请求发送到远程服务器

时间:2014-05-20 19:18:50

标签: java http ssh jsch tcp-ip

其他Java程序员。我一直面临着使用SSH连接到服务器从另一台服务器加载网页的任务。很快我发现我对网络协议的了解非常有限。首先,我尝试了动态端口转发 - 无济于事,它仅在商业图书馆中可用(并且所有这些都是我的财务范围内的FAR)。然后我了解到,使用JSch,你实际上可以创建一个叫做直接tcp-IP通道的东西(我还在努力抓住它的概念),我在stackoverflow上发现了一些应该用来发送HTTP的代码使用JSch通过SSH连接到另一台服务器请求远程服务器。这是代码(稍微修改了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建议添加端口转发)

2 个答案:

答案 0 :(得分:1)

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会话或频道。

答案 1 :(得分:-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连接)到另一个服务器 - 实际上您现在正在创建一个代理。