我需要从几台 Windows 计算机提供对共享主机上的远程文件夹的访问。该托管服务只为我提供 SSH 和一个用户帐户。无法在服务器上创建更多 SSH 用户或本地帐户。我不希望这些计算机的用户知道 SSH 密码,以避免他们拥有对 SSH 控制台的完全访问权限。出于同样的原因,我什至不想为他们提供不同的 SSH rsa 密钥。
所以,这是我解决这个问题的方法:开发一个.Net应用程序,使用WinFsp + SSHFS-Win将此远程文件夹映射到Windows驱动器,执行命令“net use”自动挂载驱动器,这样用户就不需要不必知道密码。密码被加密在代码内部,加密算法复杂且混淆,因此这些用户很难反编译代码并解密密码。我知道这个解决方案不是 100% 安全,但在这种情况下对我来说已经足够了。
当我使用 C# Process 执行下面的命令时,一切都像魅力一样工作(必须安装 WinFsp 和 SSHFS-Win)。
net use S: \\sshfs\ssh_user@host\shared_folder [decrypted_password] /user:ssh_user
但是在进程执行期间,密码在任务管理器(详细信息选项卡 > 命令行)上可见,我认为这是不可接受的。
为了避免这种情况,我尝试了以下方法:
net use S: \\sshfs\ssh_user@host\shared_folder * /user:ssh_user
现在进程等待用户输入密码。在这种情况下,我可以使用 SendKeys.Send 从代码中自动输入密码,但随后可以使用任何键盘记录器轻松提取密码。解决方案应该是重定向标准输入,以便我可以从代码将密码发送到进程,但这根本不起作用。当我使用以下代码时,命令响应“访问被拒绝”错误。
这不起作用:
Process proc = new() {
StartInfo = new("net") {
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
Arguments = @"use S: \\sshfs\ssh_user@host\shared_folder * /user:ssh_user"
}
};
proc.Start();
proc.StandardInput.WriteLine(decryptedPassword);
proc.StandardInput.Close();
proc.WaitForExit();
我已经用其他命令而不是“net use”测试了这段代码,它运行得很好。例如,如果我使用 sort 命令对其进行测试,该命令也等待用户的输入,则密码将毫无问题地作为输入传递给命令:
Process proc = new() {
StartInfo = new("sort") {
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true
}
};
proc.Start();
proc.StandardInput.WriteLine(decryptedPassword);
proc.StandardInput.Close();
Debug.WriteLine(proc.StandardOutput.ReadToEnd());
proc.WaitForExit();
现在我可以看到 Visual Studio 调试控制台上打印的密码,所以我知道代码是正确的。
我怀疑“net use”命令(或者可能是 SSHFS-Win)在某种程度上不允许输入重定向,并且需要在键盘上实际输入密码。为了确认这一点,我直接在 Windows 命令提示符(cmd.exe)上测试了以下命令,但总是得到“访问被拒绝”:
echo password | net use S: \\sshfs\ssh_user@host\shared_folder * /user:ssh_user
echo(password|net use S: \\sshfs\ssh_user@host\shared_folder * /user:ssh_user
echo|set /p=password|net use S: \\sshfs\ssh_user@host\shared_folder * /user:ssh_user
任何人都可以确认是否无法使用 net use 命令进行输入重定向吗?或者我做错了什么?有人有其他解决方案吗?
最后,我通过执行 sshfs-win.exe 而不是“net use”解决了这个问题。使用 sshfs-win.exe,标准输入重定向可以正常工作,正如预期的那样。
Process proc = new() {
StartInfo = new("C:/Program Files/SSHFS-Win/bin/sshfs-win.exe") {
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
Arguments = @"svc \sshfs\ssh_user@host\shared_folder S:"
}
};
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.StandardInput.WriteLine(decryptedPassword);
proc.StandardInput.Close();
此外,这在直接在 Windows 命令提示符下执行时也有效:
cd "C:\Program Files\SSHFS-Win\bin"
echo(password|sshfs-win.exe svc \sshfs\ssh_user@host\shared_folder S: