Java JSch create channel to access remote server v

2020-05-09 18:22发布

问题:

Using the code at http://www.jcraft.com/jsch/examples/StreamForwarding.java.html, I have tried to create code that uses JSch to connect to an SSH server, then use it to connect to a server in the Web and pass HTTP(s) requests to the server, basically using the SSH server as a proxy. Here is what I have:

    //SSH server and credentials
    String host = "00.000.000.00";
    String user = "login";
    String password = "password";
    int port = 22;

    //The host I want to send HTTP requests to - the remote host
    String remoteHost = "test.com";
    int remotePort = 80;

    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();

        Channel channel = session.getStreamForwarder(remoteHost, remotePort);

        //The GET request
        String cmd = "GET /foo/foo 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();
    }

This all sounds fine in theory, but in reality it doesn't work. I think that I could probably implement local port forwarding to make it work, but I don't understand how. Could somebody please help me out?

回答1:

Channel channel = session.getStreamForwarder(remoteHost, remotePort);
[...]
InputStream in = channel.getInputStream();
OutputStream out = channel.getOutputStream();
[...]
while ((numRead = is.read(bytes)) >= 0)
    out.write(bytes, 0, numRead);
[...]
channel.disconnect();
session.disconnect();
[...]
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
for (String line; (line = reader.readLine()) != null;){

You are closing the channel and dropping the SSH session immediately after sending the HTTP command. If the remote HTTP server isn't logging the request, it's very possibly because you dropped the session before the remote sshd instance had a chance to forward the request to the HTTP server.

Reading the response from the channel which you've already closed isn't going to work either.

Don't close the channel or the session until you're done with them.



回答2:

How about reading data from 'in' stream before executing 'channel.disconnect()'?