我想在装有 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);
}
当这个函数运行时,我可以成功连接到远程电脑,output1 有正确的值,但是 output2 和 output3 是空的。实际上很明显,在 sudo 命令之后需要输入密码。 我读过大多数关于 ssh .net 的问题。一些类似的问题一直没有得到解答。
SSH .NET : freeze upon sudo su - user2 (他或她不知道密码,但我知道我不知道如何通过代码输入)
How to su with SSH.Net? (我使用了 create shell 方法,但我无法理解它的用途,就像这个问题一样,我得到了“Last login: ...”输出。)
最佳答案
正如评论中已经提到的那样,最安全的方法是使用 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 流,那么您可以(取决于安全设置)通过标准输入提供密码。这是不安全的,因为命令会记录在不同的地方,您可能会向其他具有根访问权限的用户泄露您的密码。如果您是唯一的用户,或者您不在乎其他人能否看到您的密码,那么这对您来说可能更方便。
例子:
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'
关于c# - 如何通过 sudo 运行命令并通过 ssh .net c# 输入密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41555597/