c# - 如何通过 sudo 运行命令并通过 ssh .net c# 输入密码

标签 c# linux ssh ssh.net

我想在装有 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/

相关文章:

c# - MasterDetail 汉堡包菜单在按下后退按钮时消失

c# - 为所有 future 项目永久添加库

c# - 为什么 '\n' 在这种情况下不执行新行?

linux - 是否可以为 Linux/ARM 构建和运行 Go 插件?

ssh - ssh_config 中的多个 LocalForward

c# - 自定义文件属性

Linux bash 迭代 apache access_log 文件并发送邮件

java - 通过 Python 脚本运行的 Java 类的输出,该脚本又由 Apache Web 服务器执行

ssh - 从Aptana Studio 3终端连接到远程主机

java - 在 Unix 上使用 Java 验证 SSH 凭据