【问题标题】:Doing sudo with SSH.NET SFTP to access files使用 SSH.NET SFTP 执行 sudo 以访问文件
【发布时间】:2021-12-01 19:28:23
【问题描述】:

我正在尝试使用SSH.NET 通过 SFTP 从服务器读取/下载文件。连接工作;我可以枚举感兴趣的目录;但是当我尝试读取文件内容时,出现消息“权限被拒绝”的异常。 (下面的堆栈跟踪;我没有看到任何其他有用的东西——没有内部异常。)

这可能是问题:当我 ssh 进入服务器(使用相同的密钥)时,我必须执行 sudo vim 来查看文件内容,否则它也会给我“没有权限”。请注意,它不会让我输入密码来使用sudo。我只是不确定这如何通知我的代码更改。

using Renci.SshNet;
using System;
using System.IO;
using System.Text;

...

try {

    ConnectionInfo connectionInfo;
    using (var keyStream = new MemoryStream(Encoding.UTF8.GetBytes(GetSshKey())))
    {
        connectionInfo = new ConnectionInfo(Domain, Username,
                new PrivateKeyAuthenticationMethod(Username, new PrivateKeyFile(keyStream)));
    }

    // Connect to the server with SFTP
    using var client = new SftpClient(connectionInfo);
    client.Connect();
    if (!client.Exists(RemoteFolder))
    {
        throw new Exception("The backup folder was not found!");
    }

    // Save block blobs to local files
    foreach (var file in client.ListDirectory(RemoteFolder))
    {
        if (!file.IsRegularFile) continue; // Skip any directories or links

        var readStream = client.OpenRead(file.FullName);       // Exception thrown HERE!
        var writeStream = File.OpenWrite($"C:\\temp\\{file.Name}");

        readStream.CopyTo(writeStream);

        writeStream.Dispose();
        readStream.Dispose();
    }

} catch (Exception e)
{
    throw e;
}

堆栈跟踪:

   at Renci.SshNet.Sftp.SftpSession.RequestOpen(String path, Flags flags, Boolean nullOnError)
   at Renci.SshNet.Sftp.SftpFileStream..ctor(ISftpSession session, String path, FileMode mode, FileAccess access, Int32 bufferSize)
   at Renci.SshNet.SftpClient.Open(String path, FileMode mode, FileAccess access)
   at Renci.SshNet.SftpClient.OpenRead(String path)
   at Playground.Program.Main(String[] args) in C:\...\Program.cs:line 40 

我尝试了DownloadFileBeginDownloadFileEndDownloadFile,但在这些情况下DownloadFileEndDownloadFile 分别抛出一个类似的“权限被拒绝”错误。堆栈跟踪:

   at Renci.SshNet.Common.AsyncResult.EndInvoke()
   at Renci.SshNet.Common.AsyncResult`1.EndInvoke()
   at Renci.SshNet.Sftp.SftpSession.EndOpen(SftpOpenAsyncResult asyncResult)
   at Renci.SshNet.ServiceFactory.CreateSftpFileReader(String fileName, ISftpSession sftpSession, UInt32 bufferSize)
   at Renci.SshNet.SftpClient.InternalDownloadFile(String path, Stream output, SftpDownloadAsyncResult asyncResult, Action`1 downloadCallback)
   at Renci.SshNet.SftpClient.DownloadFile(String path, Stream output, Action`1 downloadCallback)
   at Playground.Program.Main(String[] args) in C:\...\Program.cs:line 41

【问题讨论】:

    标签: c# .net ssh sftp ssh.net


    【解决方案1】:

    您用于通过 SSH.NET 登录的帐户没有文件的读取权限。

    SFTP 协议中没有与sudo 等效的功能。

    虽然如果您连接到 OpenSSH 服务器,您可以使用以下命令指示它以提升的权限运行 SFTP 子系统/服务器:

    sudo /bin/sftp-server
    

    但是您不能直接使用 SSH.NET 来执行此操作。不过,通过对其代码进行一些修改,它可能是可行的。 SSH.NET 毕竟是开源的。

    有关更多背景信息,请参阅 WinSCP 常见问题解答How do I change user after login (e.g. su root)?

    在你开始破解它之前,先在 WinSCP GUI 中尝试确保它是可行的。


    另一种选择是在 shell (SshClient.RunCommand) 中使用 sudo 来制作您的 SFTP 帐户可以访问的文件副本。但这取决于您的sudo 权限。


    或者你也可以试试WinSCP .NET assembly,代码如下:

    SessionOptions sessionOptions = new SessionOptions
    {
        Protocol = Protocol.Sftp,
        HostName = "example.com",
        UserName = "username",
        Password = "password",
        SshHostKeyFingerprint = "...",
    };
    
    sessionOptions.AddRawSettings("SftpServer", "sudo /bin/sftp-server");
    
    using (Session session = new Session())
    {
        session.Open(sessionOptions);
    
        // Your code
    }
    

    (我是 WinSCP 的作者)


    最好的选择是直接使用对文件具有读取权限的帐户登录。

    有关此主题的一般讨论,请参阅:
    Allowing automatic command execution as root on Linux using SSH

    【讨论】:

    • 我可以使用SshClient.RunCommand 创建一个可以通过 SFTP 复制的压缩包——让事情变得简单。我确实也看过 WinSCP,它将来可能会派上用场。谢谢!
    猜你喜欢
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 2022-01-01
    • 1970-01-01
    • 2023-04-01
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多