Запускать удаленные команды через SSH-туннель в Java
Мне нужно выполнить некоторые команды с удаленного компьютера, используя соединение SSH, но проблема заключается в следующем:
Клиентский компьютер (под управлением Windows) подключен к сети, где я вижу удаленный сервер (второй компьютер * nix, в той же сети). Я могу делать с ним SSH-соединения, однако компьютер с файлами (работающий *nix) не находится в этой сети, я могу подключиться только через этот динамический туннель SSH, открытый на втором компьютере, где я обычно использую PuTTY для настроить это соединение. Тогда у меня есть доступ к удаленным файлам.
На следующем рисунке представлена архитектура (брандмауэр похож на второй компьютер):
Мне нужно сделать эту работу автоматически, поэтому я провел некоторый тест с Java и библиотекой JSch, вот код:
/* Direccion y puerto del host local */
String host = "localhost";
int lport = 5040;
/* Direccion y puerto del host remoto*/
String rhost = "localhost";
int rport = 80;
/* Usuario y password para conectarse al servidor ssh*/
String user = "test";
String pwd = "test";
JSch jsch=new JSch();
Session session=jsch.getSession(user, host, 22);
session.setPassword("test");
Properties config = new Properties();
config.put("StrictHostKeyChecking","no");
session.setConfig(config);
session.connect();
int assinged_port=session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);
Я получил соединение, однако, когда я запускаю команду, используя объект session
Ответ от второй машины, а не от третьей машины, как я ожидал. Я хотел бы знать, есть ли другая библиотека, которая помогает сделать это, или я использую неправильный JSch.
3 ответа
Конечно, если вы установите rhost = "localhost"
соединение будет установлено на SSH-сервере, а не на сервере "Resource". Введите правильное имя хоста, и это не должно быть проблемой. (Я сделал это один раз.)
Если вы хотите выполнить оба соединения из JSch, вместо переадресации локального порта, а затем подключения к этому перенаправленному порту, вы можете использовать мой ProxySSH
класс, чтобы найти в вики JSch. (Я сделал это тоже в аналогичной ситуации, как у вас там.)
Вы должны открыть другой сеанс, который использует перенаправленный порт.
Session sessionA = jsch.getSession("usernameA", "hostA");
// ...
sessionA.connect();
int forwardedPort = 2222; // any port number which is not in use on the local machine
sessionA.setPortForwardingL(forwardedPort, "hostB", 22);
Session sessionB = jsch.getSession("usernameB", "localhost", forwardedPort);
// ...
sessionB.connect();
// Use sessionB here to execute your command
Вы должны создать сеанс на втором сервере после переадресации портов. Затем устанавливается соединение с сервером за брандмауэром.
Посмотрите на этот код, например. Что этот код делает, это создает локальный порт, перенаправляющий на порт ssh в целевой системе, а затем соединяется через него. Запуск команды hostname показывает, что она действительно выполняется в перенаправленной системе.