c# - 在 C# 中连接到 AWS Managed SFTP 服务器时 SSH.NET 超时

标签 c# amazon-web-services ssh sftp ssh.net

我在尝试建立与 AWS 托管 SFTP 服务器的连接时遇到问题。使用我手头的凭据,我可以使用 sftp 命令从我的 Windows 命令行连接到服务器。这是我的 .NET 代码:

using (var client = new SshClient(new ConnectionInfo(baseHost, user,
            new AuthenticationMethod[]{
                new PrivateKeyAuthenticationMethod(user,new PrivateKeyFile[]{
                    new PrivateKeyFile(keyLocation, pkpassword)
                }),
            }
        )))
{
    client.Connect(); // Timeout here
}

上面的代码到达 client.Connect() 行,然后在 30 秒后超时并出现 Renci.SshNet.Common.SshOperationTimeoutException 异常。当我查看 Wireshark 发生的情况时,我看到 sftp 命令行实用程序使用的协议(protocol)是 SSH,而 SSH.NET 使用的是 TCP,并且数据包大小完全不同。

有人知道我在这里可能遗漏了什么吗?

我在运行上述代码的同一台计算机上运行 sftp 命令行实用程序。下面的第一个 Wireshark 图像来自上面的 C# 代码。第二个来自 sFTP 实用程序:

Wireshark Capture from C# Code

Wireshark Capture from sFTP utility

当我尝试在原始模式下使用 PuTTY 连接到服务器的端口 22 时,我没有收到任何响应。

谢谢,吉姆

最佳答案

这是旧版本 SSH.NET 和 Amazon Managed SFTP 服务器端的错误。


根据 RFC 4253 Section 4.2. Protocol Version Exchange :

When the connection has been established, both sides MUST send an identification string.

SSH.NET 客户端和 Amazon Managed SFTP 服务器均未满足此要求。双方在发送自己的之前首先等待对方发送标识字符串。死锁是不可避免的(只有超时才会中断)。这也解释了为什么 Wireshark 不将 session 识别为 SSH,因为根本没有数据交换。因此,无法识别协议(protocol)。

如果您可以修改 SSH.NET 源代码,请在 Session.Connect 中移动此行:

SocketAbstraction.Send(_socket, Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0}\x0D\x0A", ClientVersion)));

...在此 block 之上:

Match versionMatch;

//  Get server version from the server,
//  ignore text lines which are sent before if any
while (true)
{
    ...
}

...应该可以解决问题。

同时考虑向亚马逊报告错误。

我有reported the bug to SSH.NET 包括 needed change .从 SSH.NET 2020.0.0 开始包含该修复程序。


如果您无法更改 SSH.NET 代码,则需要使用另一个 SFTP 库。

例如我的WinSCP .NET assembly与 Amazon Managed SFTP 服务器兼容。

这相当于您的代码:

// Set up session options
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Sftp,
    HostName = baseHost,
    UserName = user,
    SshHostKeyFingerprint = ...,
    SshPrivateKeyPath = keyLocation,
    PrivateKeyPassphrase = pkpassword,
};

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    // Your code
}

WinSCP GUI 可以 generate a code template就像上面给你的一样。

关于c# - 在 C# 中连接到 AWS Managed SFTP 服务器时 SSH.NET 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54014749/

相关文章:

c# - 无法解决(到目前为止)的序列化错误

c# - 在使用长度前缀反序列化之前读取长度前缀

c# - 为什么 CLR 为匿名方法创建新类?

c# - asp.net 5 MVC 6 web api访问现有数据库

amazon-web-services - 如何在特定时间后自动删除 AWS Cognito 用户

python - 无法使用 python 解析 boto3 客户端 json 响应

ssh - 使用 screen 的多选项卡 SSH 客户端

shell - 不关闭ssh

amazon-web-services - AWS SES 从任何地址发送邮件

python - 在没有登录的情况下使用 ssh-agent