SSH .NET:冻结 sudo su - user2 [英] SSH .NET : freeze upon sudo su - user2
问题描述
我正在编写一个非常小的 C# 程序,旨在允许我远程连接到服务器通过 SSH(使用 SSH .NET 客户端库),并执行命令,主要是有关打印机的命令,例如lpstat".在此之前,我曾经为此目的使用 Putty 并手动检查内容(主要是打印机状态).我想自动化其中的一些.使用 Putty 我正在与 user1 连接(在连接后提示输入用户/密码时)并且必须sudo su - user2"才能执行 lpstat 和其他命令.
现在问题来了:一旦我连接到 SSH .NET,命令sudo su -"似乎冻结了连接.为什么 ?这可能与 Serverfault 中的问题相同吗?如果有另一种方式以 user2 身份连接(即以不同的方式使用 SSH .NET),那对我来说没问题.
重要说明:
- 我不知道 user2 或 root 的密码
- 这是一个生产服务器.我不是它的管理员,也不是非常高级的 Unix 用户.我不想改变那个服务器配置.
- 我相信冻结与要求密码,但我不确定.
我当前的代码:
使用系统;使用 System.Collections.Generic;使用 System.Linq;使用 System.Text;使用 Renci.SshNet;使用 System.IO;使用 System.Threading;命名空间 SSHChecker{课程计划{static void Main(string[] args){SshClient sshClient = 新 SshClient("知识产权",666,//端口"用户 1","user1Password");sshClient.Connect();sshCommand sshCommand;字符串资源;//sshCommand = sshClient.RunCommand("ls d/");//工作正常sshCommand = sshClient.RunCommand("sudo su - user2");//冻结...sshCommand = sshClient.RunCommand("ls d/");//... 所以这段代码永远不会被执行.sshClient.Disconnect();}}}
你的(6 年零 4 个月前)问题解决了吗?
我遵循了他/她的回答并且工作得很好.
- 我使用了 CentOS 7 服务器(无需安装
expect
). - Visual Studio 2017
下面是他/她的代码和示例
private static void WriteStream(string cmd, ShellStream stream){stream.WriteLine(cmd + "; echo this-is-the-end");while (stream.Length == 0)线程睡眠(500);}私有静态字符串 ReadStream(ShellStream 流){StringBuilder 结果 = new StringBuilder();字符串线;while ((line = stream.ReadLine()) != "this-is-the-end")result.AppendLine(line);返回结果.ToString();}private static void SwithToRoot(string password, ShellStream stream){//登录并获取用户提示string prompt = stream.Expect(new Regex(@"[$>]"));//Console.WriteLine(提示);//发送命令并期待密码或用户提示stream.WriteLine("su - root");prompt = stream.Expect(new Regex(@"([$#>:])"));//Console.WriteLine(提示);//检查发送密码如果(提示.包含(:")){//发送密码流.WriteLine(密码);prompt = stream.Expect(new Regex(@"[$#>]"));//Console.WriteLine(提示);}}
示例:
using (var client = new SshClient(server, username, password)){客户端连接();列表<字符串>命令 = 新列表<字符串>();命令.添加(密码");commands.Add("cat/etc/sudoers");ShellStream shellStream = client.CreateShellStream("xterm", 80, 24, 800, 600, 1024);//切换到rootSwithToRoot("rootpassword", shellStream);//在root账户下执行命令foreach(命令中的字符串命令){写流(命令,shellStream);字符串答案 = ReadStream(shellStream);int index = answer.IndexOf(System.Environment.NewLine);answer = answer.Substring(index + System.Environment.NewLine.Length);Console.WriteLine("命令输出:" + answer.Trim());}客户端断开连接();}
其他一些解释
<块引用>我不知道 user2 或 root 的密码
在服务器设置中,用户可以在不提示密码的情况下切换帐户.
<块引用>ls d/
必须是 ls -d/
.
它只是在服务器的控制台上显示结果/输出,为了看到结果,使用ReadStream
函数.
I am writing a very small C# program designed to allow me to connect remotely to a server via SSH (using SSH .NET Client Library), and execute commands, mainly commands about printers such as 'lpstat'. Until here I used to use Putty for that purpose and check stuff (mainly printers states) manually. I would like to automate some of this. Using Putty I was connecting with user1 (when prompted for a user/password just after connecting) and had to "sudo su - user2" to then be able to execute lpstat and others commands.
Now here is the problem : Once I am connected with SSH .NET, the command "sudo su - " seems to freeze the connection. Why ? Could it be the same problem as this one from Serverfault ? If there is another way to be connected as user2 (ie using SSH .NET differently), that would be fine with me.
Important notes:
- I don't know user2's or root's password
- It is a production server. I am not its administrator, and I am not a very advanced Unix user. I do not want to alter that server configuration.
- I believe the freeze has to do with the command asking for a password, but I'm not sure.
My current code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Renci.SshNet;
using System.IO;
using System.Threading;
namespace SSHChecker
{
class Program
{
static void Main(string[] args)
{
SshClient sshClient = new SshClient(
"IP",
666, // port
"user1",
"user1Password");
sshClient.Connect();
SshCommand sshCommand;
String res;
//sshCommand = sshClient.RunCommand("ls d /"); // works fine
sshCommand = sshClient.RunCommand("sudo su - user2"); // freezes ...
sshCommand = sshClient.RunCommand("ls d /"); // ... so this code is never executed.
sshClient.Disconnect();
}
}
}
Have you fixed your (6 years, 4 months ago) question?
This user kasbst from github answered here
I followed his/her answer and worked very well.
- I used CentOS 7 server (no need install
expect
). - Visual Studio 2017
Below is his/her code and sample
private static void WriteStream(string cmd, ShellStream stream)
{
stream.WriteLine(cmd + "; echo this-is-the-end");
while (stream.Length == 0)
Thread.Sleep(500);
}
private static string ReadStream(ShellStream stream)
{
StringBuilder result = new StringBuilder();
string line;
while ((line = stream.ReadLine()) != "this-is-the-end")
result.AppendLine(line);
return result.ToString();
}
private static void SwithToRoot(string password, ShellStream stream)
{
// Get logged in and get user prompt
string prompt = stream.Expect(new Regex(@"[$>]"));
//Console.WriteLine(prompt);
// Send command and expect password or user prompt
stream.WriteLine("su - root");
prompt = stream.Expect(new Regex(@"([$#>:])"));
//Console.WriteLine(prompt);
// Check to send password
if (prompt.Contains(":"))
{
// Send password
stream.WriteLine(password);
prompt = stream.Expect(new Regex(@"[$#>]"));
//Console.WriteLine(prompt);
}
}
Sample:
using (var client = new SshClient(server, username, password))
{
client.Connect();
List<string> commands = new List<string>();
commands.Add("pwd");
commands.Add("cat /etc/sudoers");
ShellStream shellStream = client.CreateShellStream("xterm", 80, 24, 800, 600, 1024);
// Switch to root
SwithToRoot("rootpassword", shellStream);
// Execute commands under root account
foreach (string command in commands) {
WriteStream(command, shellStream);
string answer = ReadStream(shellStream);
int index = answer.IndexOf(System.Environment.NewLine);
answer = answer.Substring(index + System.Environment.NewLine.Length);
Console.WriteLine("Command output: " + answer.Trim());
}
client.Disconnect();
}
Some other explanation
I don't know user2's or root's password
In setting of server, user can switch account without prompting password.
ls d /
It must be ls -d /
.
It just displays result/output on console of server, in order to see result, use ReadStream
function.
这篇关于SSH .NET:冻结 sudo su - user2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!