2017-01-09 5 views
0

Ich möchte Befehl ausführen und das Ergebnis auf Remote-Computer, der Linux-Betriebssystem hat. Ich verwende ssh .net-Bibliothek, um mit C# -Code zu verbinden. Ich kann verbinden und einige Befehle ausführen, die es nicht benötigt, "sudo" vorher zu verwenden. aber ich weiß nicht, wie man Befehle ausführt, die von sudo ausgeführt werden müssen, denn nach dem Ausführen - zum Beispiel - "sudo iptables -L-n" sollte ich ein Passwort eingeben und ich weiß nicht, wie ich das Passwort eingeben soll, nachdem ich das ausgeführt habe Befehl.So führen Sie Befehle von Sudo und geben Sie ein Passwort von ssh .net C#

Dies ist mein Code:

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); 
} 

, wenn diese Funktion laufen, ich erfolgreich auf Remote-PC verbinden kann, output1 richtigen Wert hat, aber output2 und output3 ist leer. Tatsächlich ist es offensichtlich, dass nach dem Sudo-Befehl ein Passwort eingegeben werden muss. Ich habe die meisten Fragen über ssh .net gelesen. Eine ähnliche Frage ist unbeantwortet geblieben.

SSH .NET : freeze upon sudo su - user2 (er oder sie knapp über das Passwort kennen, aber ich weiß, ich weiß nicht, wie es über den Code eingeben)

How to su with SSH.Net? (I verwendeten Shell-Methode erstellen, aber ich konnte nicht verstehen, was für und wie Diese Frage habe ich "Last login: ..." Ausgabe.)

+0

Was ist 'SshCommandLineRunner'? Ist es Teil der SSH.NET-Bibliothek? Der normale Weg wäre 'CreateShellStream' um einen Stream zu erhalten und die Expect und Write Methode des Streams zu verwenden. –

Antwort

1

Der sicherste Weg, um es zu tun, wie bereits in einem Kommentar erwähnt, ist CreateShellStream und schreiben Sie einfach das Passwort direkt in den Stream nach dem Ausführen der Sudo-Befehl. Das Passwort wird gesendet, als ob Sie ein interaktives Terminal verwendet hätten. Dies ist jedoch möglicherweise keine praktische Lösung, wenn Sie nicht für den Rest dessen, was Sie tun möchten, einen Endlos-Stream verwenden möchten. Beispiel:

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); 
} 

Der Nachteil ist, dass die Ausgabe Junk enthalten wird Sie nicht wirklich wollen: Steuerzeichen, Eingabeaufforderungen und alles andere, was über den Stream gesendet wird.

Wenn Sie die Verwendung eines Shell-Streams vermeiden möchten, können Sie (abhängig von den Sicherheitseinstellungen) möglicherweise ein Passwort über stdin eingeben. Dies ist ein Fehler, da Befehle an verschiedenen Stellen protokolliert werden und Sie Ihr Kennwort möglicherweise anderen Benutzern mit Root-Zugriff mitteilen. Wenn Sie der einzige Benutzer sind oder es Ihnen egal ist, dass alle anderen Ihr Passwort sehen können, ist dies möglicherweise bequemer für Sie.

Beispiel:

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); 
} 

Schließlich ist es auch möglich, ein Skript haben Ihr Passwort drucken stdin. Auf diese Weise wird Ihr Kennwort nicht zusammen mit dem Rest der Befehlszeile protokolliert. aber das ist immer noch nicht viel sicherer, da jemand mit Root-Zugriff möglicherweise das Skript lesen konnte und das Passwort finden Sie unter:

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); 
} 

und innen printpasswd.sh:

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

Ich benutze deine zweite Lösung. laufender Code bleibt bei var output = stream.Expect (promptRegex); in deiner ersten Lösung. –

+0

@ N_93 Wenn die erste Lösung hängt, dann war mein regulärer Ausdruck für die Übereinstimmung mit der Shell-Eingabeaufforderung einfach nicht allgemein genug für dich.Aber die 2. Lösung funktioniert gut, solange Sie Ihr Passwort in den Protokollen sehen können. – RogerN

Verwandte Themen