Я столкнулся с некоторыми проблемами с SSH, используя любую из следующих библиотек: JSCH, sshd от apache и sshj. Все они блокируются на exec channel
при попытке прочитать вывод команды, которую я запускаю, и в конечном итоге время ожидания истекает. Дело в том, что это происходит только для некоторых маршрутизаторов, на которых установлен сервер OpenSSH 4.5. Клиент отлично работает на моей виртуальной машине, где я установил последнюю возможную версию OpenSSH.
Используя Apache MINA SSHD, клиент будет:
public static void main(String[] args) throws InterruptedException, IOException {
String cmdToRun = "ls";
SshClient client = SshClient.setUpDefaultClient();
client.start();
ClientSession session = client.connect("127.0.0.1", 22).await().getSession();
session.authPassword("sshUser", "sshPass").await().isSuccess();
ChannelExec channelExec = session.createExecChannel(cmdToRun);
channelExec.setOut(System.out);
channelExec.open();
channelExec.waitFor(ClientChannel.CLOSED, 0);
channelExec.close(true);
client.stop();
}
Я отлаживаю его в Eclipse и с помощью WireShark наблюдаю за переданными и полученными сообщениями, и все выглядит нормально. Обмен DH проходит хорошо, авторизация тоже, но когда я пытаюсь открыть канал exec, в Virtual Box (где он работает) я получаю:
.....
.....
Получен SSH_MSG_USERAUTH_SUCCESS
Отправить SSH_MSG_CHANNEL_OPEN на канал 101
Ответ, который я получаю от сервера, выглядит так:
5b 00 00 00 65 00 00 00 00 00 00 00 00 00 00 80 00
5b означает SSH_MSG_CHANNEL_OPEN_CONFIRMATION
00 00 00 65 — это канал, который отправил клиент (101, конечно)
00 00 00 00 — это канал, назначенный сервером
00 00 00 00 — начальный размер окна
00 00 80 00 — максимальный размер пакета
Поскольку начальный размер окна равен 0, я сначала получаю сообщение SSH_MSG_CHANNEL_WINDOW_ADJUST
, а затем SSH_MSG_CHANNEL_SUCCESS
, что означает, что запрос (команда) был успешно выполнен. SSH_MSG_CHANNEL_REQUEST
, который содержит exit-status 0
, и SSH_MSG_CHANNEL_DATA
, который содержит результат моей команды ls
, позже обмениваются, как и ожидалось.
Теперь на маршрутизаторе с OpenSSH 4.5 сообщение 5b выглядит немного иначе:
5b 00 00 00 65 00 00 00 00 00 02 00 00 00 00 80 00
Как мы видим, начальное окно установлено, поэтому нет необходимости получать SSH_MSG_CHANNEL_WINDOW_ADJUST
. Я получаю SSH_MSG_CHANNEL_SUCCESS
, и все, потом останавливается. Он не получает ни SSH_MSG_CHANNEL_REQUEST
, содержащего статус выхода команды, ни SSH_MSG_CHANNEL_DATA
, как показано в предыдущем примере. Wireshark это подтверждает.
Почему это происходит? Почему я не получаю результат, если получаю SSH_MSG_CHANNEL_SUCCESS
, что подтверждает успешность запроса?
Это происходит со всеми различными клиентскими библиотеками, которые я использую, так или иначе, они истекают. Все работает нормально, если я открываю канал shell
, но я не хочу использовать интерактивный сеанс. Для команд, которые имеют много страниц, вы должны прочитать каждую строку, посмотреть, нужно ли вам что-то нажимать, чтобы продолжить и т. д.
Должен ли я просто сдаться? Может быть, OpenSSH 4.5 не разрешает exec
каналов? Почему нет ни одной ошибки?