繁体   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