2017-01-09 2 views
0

Я хочу запустить команду и получить результат на удаленном компьютере с операционной системой Linux. Я использую библиотеку ssh .net для подключения по C# -коду. Я могу подключить и запустить некоторые команды, которые не нужно использовать «sudo». но я не знаю, как выполнять команды, которые должны выполняться sudo, потому что после запуска -for instance- «sudo iptables -L -n» я должен ввести пароль, и я не знаю, как ввести пароль после выполнения этого команда.Как запустить команды sudo и ввести пароль по ssh .net C#

Это мой код:

private void connectingToLinuxHost(string ip, string username, string password, int port) 
{ 
    SshCommandLineRunner ssh = new SshCommandLineRunner(ip, username, password, port); 
    ssh.Connect(); 
    string output1 = ssh.ExecuteCommand("ls"); 

    ssh.ExecuteCommand("sudo iptables -L -n"); 
    Thread.Sleep(1000); 
    string output2 = ssh.ExecuteCommand(password); 

    ssh.ExecuteCommand("sudo iptables -L -n \n"); 
    Thread.Sleep(1000); 
    string output3 = ssh.ExecuteCommand(password); 
} 

, когда эта функция запуска, я могу подключиться к удаленному ПК успешно, output1 имеет правильное значение, но output2 и output3 пустуют. на самом деле очевидно, что после команды sudo необходимо ввести пароль. Я прочитал большинство вопросов о ssh .net. такой же вопрос остается без ответа.

SSH .NET : freeze upon sudo su - user2 (он или она не знает пароль, но я знаю, что я не знаю, как ввести его с помощью кода)

How to su with SSH.Net? (я использовал метод создания оболочки, но я не мог понять, что для и как этот вопрос я получил «Последний вход: ...».)

+0

Что такое 'SshCommandLineRunner'? Является ли он частью библиотеки SSH.NET? Обычным способом будет «CreateShellStream» для получения потока и использования метода Expect и Write для потока. –

ответ

1

Самый безопасный способ сделать это, как уже упоминалось в комментарии, это использовать CreateShellStream и просто написать пароль непосредственно в поток после запуска команда sudo. Пароль отправляется так же, как если бы вы использовали интерактивный терминал. Это может быть не простое решение, хотя, если вы не хотите, чтобы вас запирали бесконечным потоком для остальной части того, что вы хотите сделать. Пример:

var promptRegex = new Regex(@"\][#$>]"); // regular expression for matching terminal prompt 
var modes = new Dictionary<Renci.SshNet.Common.TerminalModes, uint>(); 
using (var stream = ssh.CreateShellStream("xterm", 255, 50, 800, 600, 1024, modes)) 
{ 
    stream.Write("sudo iptables -L -n\n"); 
    stream.Expect("password"); 
    stream.Write("mypassword\n"); 
    var output = stream.Expect(promptRegex); 
} 

Недостатком является то, что ваш выход будет включать в себя мусор вы действительно не хотите: управляющие символы, подсказки, и все остальное, что отправляется через поток.

Если вы хотите избежать использования потока оболочки, то вы можете (в зависимости от настроек безопасности) предоставить пароль через stdin. Это НЕЗАКОННО, потому что команды регистрируются в разных местах, и вы можете показывать свой пароль другим пользователям с правами доступа root. Если вы единственный пользователь, или вам все равно, что все остальные могут видеть ваш пароль, то это может быть более удобным для вас.

Пример:

using (var cmd = ssh.RunCommand("echo -e 'mypassword\n' | sudo -S iptables -L -n")) 
{ 
    if (cmd.ExitStatus == 0) 
     Console.WriteLine(cmd.Result); 
    else 
     Console.WriteLine(cmd.Error); 
} 

Наконец, это также возможно, чтобы иметь сценарий печати пароль на STDIN. Таким образом, ваш пароль не будет регистрироваться вместе с остальной частью командной строки; но это еще не намного безопаснее, так как любой человек с доступом корня потенциально может прочитать сценарий и увидеть пароль:

using (var cmd = ssh.RunCommand("~/printpasswd.sh | sudo -S iptables -L -n")) 
{ 
    if (cmd.ExitStatus == 0) 
     Console.WriteLine(cmd.Result); 
    else 
     Console.WriteLine(cmd.Error); 
} 

и внутри printpasswd.sh:

#!/bin/bash 
echo -e 'mypassword\n' 
+0

Я использую ваше второе решение. запущенный код, застрявший в var output = stream.Expect (promptRegex); в вашем первом решении. –

+0

@ N_93 Если первое решение висит, то мое регулярное выражение для совпадения командной строки просто недостаточно для вас.Но второе решение будет работать нормально, пока вы в порядке, когда ваш пароль будет виден в журналах. – RogerN

Смежные вопросы