JSch - переадресация портов с использованием нескольких Jumphosts

Для отладки удаленных систем AS / 400 мне нужно настроить SSH-соединение, которое запускает 2 или более хостов перехода для доступа к целевой системе. Я уже сделал большую часть (например, настройку портов панели инструментов JTopen, которые используются, чтобы иметь возможность переопределить их локально). ).

Единственное, я не могу заставить JSch делать то, что переносит порт локального хоста через несколько хостов к целевому порту на AS / 400.

Пример

[локальный-порт 1234] ==> [ssh-jumphost-1] ===> [ssh-jumphost-2] ===> [as400-порт 8470]

Я пробовал и играл с примерами JSch, и могу заставить работать примеры ForwardL и Jumphost, но при их объединении (настройка туннеля, а затем установка перенаправления порта as / 400 на первый хост)

Я также пытался сделать это с помощью SSH (чтобы посмотреть, возможно ли это вообще), но и здесь не повезло.

Вопросы: 1. Возможно ли вообще то, что я пытаюсь сделать? или этого невозможно добиться? 2. JSch не подходит для работы? следует ли использовать другую библиотеку Java SSH2 для большего успеха?

Если нужно, я тоже могу опубликовать код.

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import eu.javautil.sshtool.config.JumpHost;
import eu.javautil.sshtool.config.JumpHostChain;

import java.util.HashMap;
import java.util.Map;

/**
 * Manages SSH Tunnels
 *
 * @author fhdumay
 * @version 1.0.0
 */
public class SSHTunnel {
    private final JumpHostChain sshChain;
    private final Session[] sessions;
    private final JSch jSchInstance;
    private boolean tunnelActive = false;

    /**
     * @param sshChain
     */
    public SSHTunnel(JumpHostChain sshChain) {
        jSchInstance = new JSch();
        jSchInstance.setLogger(new MyLogger());
        this.sshChain = sshChain;
        sessions = new Session[sshChain.getAdditionalJumpHosts().length + 1];
    }

    /**
     *
     * @throws JSchException
     */
    public void createTunnel() throws JSchException {
        int index = 0;

        synchronized (sshChain) {
            if (tunnelActive) {
                return;
            }

            Session session;

            sessions[index++] = session = createSession(jSchInstance, sshChain.getPrimaryJumpHost(), sshChain.getPrimaryJumpHost().getSSHPortNumber());;

            for (JumpHost jh : sshChain.getAdditionalJumpHosts()) {
                // Step 1: setup the forwarding FIRST.....
                int assignedPort = session.setPortForwardingL(0, jh.getServer().getServerAddress().getPreferredAddress(), jh.getSSHPortNumber());

                // Step 2: Create the session for the 'forwarded-to' host
                sessions[index++] = session = createSession(jSchInstance, jh, assignedPort);
            }
            tunnelActive = true;
        }
    }

    /**
     *
     * @return
     */
    public boolean isTunnelActive() {
        synchronized (sshChain) {
            return tunnelActive;
        }
    }

    /**
     *
     */
    public void closeTunnel() {
        synchronized (sshChain) {
            if (!tunnelActive) {
                return;
            }

            for (int i = sessions.length - 1; i >= 0; i--) {
                sessions[i].disconnect();
                sessions[i] = null;
            }

            tunnelActive = false;
        }
    }

    private final Map<String, Map<Integer, Integer>> availablePortForwarding = new HashMap<String, Map<Integer, Integer>>();

    /**
     *
     * @param address
     * @param portsToForward
     * @return
     * @throws JSchException
     */
    public Map<Integer, Integer> forwardPorts(String address, int[] portsToForward) throws JSchException {
        synchronized (sshChain) {
            if (!tunnelActive) {
                throw new IllegalStateException("Tunnel as not been setup ");
            }

            Map<Integer, Integer> availableMappings = availablePortForwarding.containsKey(address)
                    ? availablePortForwarding.get(address)
                    : new HashMap<Integer, Integer>()
                    ;
            Map<Integer, Integer> portMap = new HashMap<Integer, Integer>();

            Session session = sessions[0];    // The last jump host chain *SHOULD* be able to connect to the target host !

            for (int portNo : portsToForward) {
                if (availableMappings.containsKey(portNo)) {
                    portMap.put(portNo, availableMappings.get(portNo));
                } else {
                    int assignedPort = session.setPortForwardingL(0, address, portNo);
                    portMap.put(portNo, assignedPort);
                    availableMappings.put(portNo, assignedPort);
                }
            }
            availablePortForwarding.put(address, availableMappings);
            return portMap;
        }
    }

    public static class MyLogger implements com.jcraft.jsch.Logger {
        static java.util.Hashtable name=new java.util.Hashtable();
        static{
            name.put(new Integer(DEBUG), "DEBUG: ");
            name.put(new Integer(INFO), "INFO: ");
            name.put(new Integer(WARN), "WARN: ");
            name.put(new Integer(ERROR), "ERROR: ");
            name.put(new Integer(FATAL), "FATAL: ");
        }
        public boolean isEnabled(int level){
            return true;
        }
        public void log(int level, String message){
            System.err.print(name.get(new Integer(level)));
            System.err.println(message);
        }
    }

    /**
     * @param jSchInstance
     * @param host
     * @param assignedPort
     *
     * @return
     *
     * @throws JSchException
     */
    private Session createSession(JSch jSchInstance, JumpHost host, int assignedPort) throws JSchException {
        String preferredAddress = (host != null ? host.getServer().getServerAddress().getPreferredAddress() : "127.0.0.1");

        int port = (host != null ? host.getSSHPortNumber() : assignedPort);
        //Credentials credentials = host.getCredentials();

        Session s = jSchInstance.getSession("<user>", preferredAddress, port);
        s.setConfig("StrictHostKeyChecking", "no");
        s.setPassword("<password>");

        s.connect();
        System.out.println("Created connection: " + host);
        return s;
    }
}

person Tiger-Lilly    schedule 04.02.2016    source источник
comment
Измените свой вопрос, включив соответствующий исходный код. Я предполагаю, что ссылка local- ›jumphost1 проходит через jsch? Как вы создаете ссылку jumphost1- ›jumphost2 и ссылку jumphost-2-› as400?   -  person Kenster    schedule 04.02.2016
comment
Я добавил код, как и просили. Идея, которую я имел в виду, заключалась в создании сеанса ssh от одного jumphost к другому (я использовал это в качестве примера: jcraft.com/jsch/examples/JumpHosts.java.html). После создания туннеля я попытался настроить переадресацию порта либо на первый, либо на последний узел перехода (см .: jcraft.com/jsch/examples/PortForwardingL.java.html) Когда я затем пытаюсь подключиться к перенаправленному порту с локального хоста, я не вижу ответа, но и ошибки нет. . Если туннеля нет, я ожидал что-то вроде «в соединении отказано»   -  person Tiger-Lilly    schedule 07.02.2016