Подскажите библиотеку для работы в SSH из .NET. Пробовал SSH.net, но чего то странно она себя ведет. Все время в выводе получаю, больше чем ожидал. То перевод строки вставит, то первую строку продублирует и прочая дьявольщина Мне нужно отправлять команды на устройство и получать результат.
Здравствуйте, Cynic, Вы писали:
C>Подскажите библиотеку для работы в SSH из .NET. Пробовал SSH.net, но чего то странно она себя ведет. Все время в выводе получаю, больше чем ожидал. То перевод строки вставит, то первую строку продублирует и прочая дьявольщина Мне нужно отправлять команды на устройство и получать результат.
А нету больше. Только старый Tamir SSH и непонятная мелочёвка. Проверить легко, поиском в nuget.org.
В issues ssh.net есть вот это. Если не оно — заводите новый и прикладывайте пруфы, починят.
Здравствуйте, Cynic, Вы писали:
C>Подскажите библиотеку для работы в SSH из .NET. Пробовал SSH.net, но чего то странно она себя ведет. Все время в выводе получаю, больше чем ожидал. То перевод строки вставит, то первую строку продублирует и прочая дьявольщина Мне нужно отправлять команды на устройство и получать результат.
SSH.net использую для создания SSH tunnels несколько лет, в том числе и в массовых приложениях. Все нормально. Вчера перешел на новую версию, все ОК.
Здравствуйте, Nonmanual Worker, Вы писали:
NW>SSH.net использую для создания SSH tunnels несколько лет, в том числе и в массовых приложениях. Все нормально. Вчера перешел на новую версию, все ОК.
Ну может тогда подскажите в чём проблема.
Мне нужно опрашивать сетевые устройства Cisco и анализируя вывод команд проверять соответствие конфигурации определенным политикам. Для этого мне нужно подключиться к устройству, сделать выводы нужных команд, распарсить их и проанализировать. Используя SSH.net это можно сделать двумя способами (возможно их больше):
1) Использовать SshClient.RunCommand(string). В этом случае приходится закрывать соединение после выполнения каждой команды:
using (var sshClient = new SshClient(deviceName, login, password))
{
sshClient.Connect();
var cmdOut = sshClient.RunCommand("cmd#1").Result;
sshClient.Disconnect();
sshClient.Connect();
var cmdOut = sshClient.RunCommand("cmd#2").Result;
sshClient.Disconnect();
// и т.д.
}
2) Читать/писать из SSH-потока:
using (var sshClient = new SshClient(deviceName, login, password))
{
sshClient.Connect();
using (var shellStream = sshClient.CreateShellStream("commandTerminal", 80, 20000, 800, 600, 1024))
{
shellStream.WriteLine("cmd");
string output = string.Empty;
var result = new List<string>();
// Ожидание необходимо поскольку устройство отвечает с задержкойwhile ((output = shellStream.ReadLine(TimeSpan.FromMilliseconds(1000))) != null)
{
// Проверки ...
result.Add(output);
}
}
sshClient.Disconnect();
}
Первый способ мне не подходит, т.к. большое количество открываний/закрываний сессии генерирует событие безопасности, поэтому я использую второй.
Проблема в том, что в некоторых случаях метод ReadLine часто не возвращает тех строк которые я вижу когда использую Putty или SecureCRT. Например, некоторые роутеры Cisco имеют встроенный модуль шифрования для управления которым нужно из консоли роутера выполнить команду 'service sp 1/0 session', после чего модуль шифрования сначала выводит информационный текст, а потом приглашение на ввод логина и пароля. Так вот когда посылаешь эту команду методом WriteLine и начинаешь читать вывод, ReadLine читает баннер, а приглашение на ввод логина нет (ReadLine всё время возвращает null).
Пытаясь побороть проблему пробовал: Менять время ожидания в команде ReadLine
Читать поток по байтам командой ReadByte
Создавать потоки StreamWriter и StreamReader производные от shellStream и читать вывод их методами
Ни чего не помогло результат тот-же. Возможно конечно, что я не верно обрабатываю вывод, а Putty и SecureCRT делают это правильно, но я ума не приложу чего ещё делать
Здравствуйте, Cynic, Вы писали:
C>Ни чего не помогло результат тот-же. Возможно конечно, что я не верно обрабатываю вывод, а Putty и SecureCRT делают это правильно, но я ума не приложу чего ещё делать
Не знаю вопроса почти совсем, но — вы не замечали в putty странной формулировки про "keyboard-interactive-что-то там"? Когда логинитесь.
Здравствуйте, Слава, Вы писали:
С>Не знаю вопроса почти совсем, но — вы не замечали в putty странной формулировки про "keyboard-interactive-что-то там"? Когда логинитесь.
Оно сообщает что используется метод аутентификации через ввод данных с клавиатуры. Просто можно ещё по сертификату например.
С>Быть может, там несколько каналов IO?
Не вроде один только. Я думаю, что устройство что-то кидает в поток, что обработать ShellStream не может.
Передаём нужную в SshClient.
Если аутентификация прошла, то запроса пароля ты, очевидно, не получишь.
В случае KeyboardInteractiveConnectionInfo, необходимо подписаться на событие AuthenticationPrompt.
Обработчик AuthenticationPromtReceived(Object sender, AuthenticationPromptEventArgs e) в коллекции e.Prompts содержится Request, который ты должен проверить на приглашение о вводе пароля и Response, которому ты и должен задать пароль.
Есть мнение, что Слава прав, и в твоём случае подойдёт именно KeyboardInteractiveConnectionInfo.
На всякий случай подпишись и на событие ErrorOccurred. Вполне возможно, что произошла какая-то ошибка.
Здравствуйте, LWhisper, Вы писали:
LW>Во-первых, действительно возможно несколько вариантов аутентификации: LW>По паролю, интерактивный ввод, по ключу.
LW>Соответственно: LW>PasswordConnectionInfo LW>KeyboardInteractiveConnectionInfo LW>PrivateKeyConnectionInfo
LW>Передаём нужную в SshClient. LW>Если аутентификация прошла, то запроса пароля ты, очевидно, не получишь. LW>В случае KeyboardInteractiveConnectionInfo, необходимо подписаться на событие AuthenticationPrompt. LW>Обработчик AuthenticationPromtReceived(Object sender, AuthenticationPromptEventArgs e) в коллекции e.Prompts содержится Request, который ты должен проверить на приглашение о вводе пароля и Response, которому ты и должен задать пароль.
LW>Есть мнение, что Слава прав, и в твоём случае подойдёт именно KeyboardInteractiveConnectionInfo. LW>На всякий случай подпишись и на событие ErrorOccurred. Вполне возможно, что произошла какая-то ошибка.
Вы не поняли. Просто залогиниться на устройство и читать вывод я могу. Проблема в том, что на самом устройстве можно сделать ещё один логин на внутренний модуль. Т.е. вы логинитесь на устройство, получаете приглашение командной строки, потом вводите команду и вылезает ещё одно приглашение для логина внутри установленной сессии и вот с этого момент начинаются проблемы. Но за советы спасибо попробую
Здравствуйте, Cynic, Вы писали:
C>Вы не поняли. Просто залогиниться на устройство и читать вывод я могу. Проблема в том, что на самом устройстве можно сделать ещё один логин на внутренний модуль. Т.е. вы логинитесь на устройство, получаете приглашение командной строки, потом вводите команду и вылезает ещё одно приглашение для логина внутри установленной сессии и вот с этого момент начинаются проблемы. Но за советы спасибо попробую
Ага, понятно.
Таким не занимался, но, подозреваю, что тебе нужно получить сессию и подписаться на сообщения от неё:
MessageReceived
RegisterMessage
Здравствуйте, Cynic, Вы писали:
C>Подскажите библиотеку для работы в SSH из .NET. Пробовал SSH.net, но чего то странно она себя ведет. Все время в выводе получаю, больше чем ожидал. То перевод строки вставит, то первую строку продублирует и прочая дьявольщина Мне нужно отправлять команды на устройство и получать результат.
Почему просто не создать процесс c openssh client без всяких сомнительных враперов?
П.С. для взаимодействия с командной строкой можно накидать скрипт с http://linux.die.net/man/1/expect
Підтримати Україну у боротьбі з країною-терористом.
Здравствуйте, #John, Вы писали:
J>Здравствуйте, Cynic, Вы писали:
C>>Подскажите библиотеку для работы в SSH из .NET. Пробовал SSH.net, но чего то странно она себя ведет. Все время в выводе получаю, больше чем ожидал. То перевод строки вставит, то первую строку продублирует и прочая дьявольщина Мне нужно отправлять команды на устройство и получать результат.
J>Почему просто не создать процесс c openssh client без всяких сомнительных враперов? J>П.С. для взаимодействия с командной строкой можно накидать скрипт с http://linux.die.net/man/1/expect
Здравствуйте, Cynic, Вы писали:
J>>Почему просто не создать процесс c openssh client без всяких сомнительных враперов? J>>П.С. для взаимодействия с командной строкой можно накидать скрипт с http://linux.die.net/man/1/expect
C>А можно поподробнее ...
1. openssh-client & expect & sh можно достать из cygwin как уже готовые бинарники(+просмотреть их с dependency walker -ом и забрать вместе с зависимыми либами), либо забрать их из mingw(или скомпилить с mingw), -если ненужны зависимости ввиде либ от cygwin.
Или если надо совсем по быстрому и простому: просто поставить на сервер: cygwin(или mingw) c openssh-client и expect.
2. Накидываем скрипт, который напр., по ssh будет запускать какой-то скрипт на удаленном сервере, myscript.sh: