簡體   English   中英

如何通過 sudo 運行命令並通過 ssh .net c# 輸入密碼

[英]How to run commands by sudo and enter password by ssh .net c#

我想在具有 Linux 操作系統的遠程計算機上運行命令並獲取結果。 我正在使用 ssh .net 庫通過 C# 代碼進行連接。 我可以連接並運行一些以前不需要使用“sudo”的命令 但我不知道如何運行需要由 sudo 運行的命令,因為在運行后-例如-“sudo iptables -L -n”我應該輸入密碼,但我不知道執行此操作后如何輸入密碼命令。

這是我的代碼:

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

當這個函數運行時,我可以成功連接到遠程電腦,輸出1有正確的值,但輸出2和輸出3為空。 實際上很明顯,在 sudo 命令之后需要輸入密碼。 我已經閱讀了有關 ssh .net 的大多數問題。 一些類似的問題仍未得到解答。

SSH .NET:凍結 sudo su - user2 (他或她不知道密碼,但我知道我不知道如何通過代碼輸入)

如何使用 SSH.Net su? (我使用了 create shell 方法,但我無法理解這個問題的目的是什么,我得到了“上次登錄:...”輸出。)

正如評論中已經提到的,最安全的方法是使用 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);
}

缺點是您的輸出將包含您並不真正想要的垃圾:控制字符、提示以及通過流發送的所有其他內容。

如果您想避免使用 shell 流,那么您可以(取決於安全設置)通過 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);
}

最后,還可以讓腳本將您的密碼打印到標准輸入。 這樣您的密碼就不會與命令行的其余部分一起記錄; 但這仍然不是更安全,因為任何具有 root 訪問權限的人都可能讀取腳本並查看密碼:

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'

您可以對 Renci 庫使用相同的 bash 命令並安裝在服務器“sshpass”包中。 在這種情況下,您可以使用:

SshClient client = new SsClient(IP_server, username, password);
client.Connect();
var commandToSend = client.CreateCommand("sshpass -p \"password\" sudo iptables -L");
commandToSend.Execute();
string response = commandToSend:Result.ToString();
Console.WriteLine("Response: " + response);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM