Тайм-аут SSH.NET при подключении к управляемому SFTP-серверу AWS в C # - PullRequest
0 голосов
/ 03 января 2019

У меня проблемы с установкой соединения с управляемым SFTP-сервером AWS. Используя имеющиеся у меня учетные данные, я могу подключиться к серверу из командной строки Windows с помощью команды sftp. Вот мой код .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, - это SSH, в то время как SSH.NET использует TCP, а размеры пакетов совершенно разные.

Кто-нибудь знает, чего мне здесь не хватает?

Я запускаю утилиту командной строки sftp на том же компьютере, что и приведенный выше код. Первое изображение Wireshark ниже взято из кода C # выше. Второй из утилиты sFTP:

Wireshark Capture from C# Code

Wireshark Capture from sFTP utility

Когда я пытаюсь подключиться к порту 22 сервера, используя PuTTY в режиме raw, я не получаю ответа.

Спасибо, Джим

1 Ответ

0 голосов
/ 03 января 2019

Согласно RFC 4253, раздел 4.2. Версия протокола Exchange :

Когда соединение установлено, обе стороны ДОЛЖНЫ отправить идентификационную строку.

Клиент SSH.NET и SFTP-сервер Amazon Managed не соответствуют этому требованию. Оба сначала ждут, пока другая сторона отправит идентификационную строку, прежде чем отправлять свою собственную. Тупик неизбежен (прерывается только тайм-аутом). Это также объясняет, почему Wireshark не идентифицирует сеанс как SSH, так как данные вообще не передаются. Следовательно, ничто не позволяет идентифицировать протокол.

Если вы можете изменить исходный код SSH.NET, переместите эту строку в Session.Connect:

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

... над этим блоком:

Match versionMatch;

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

... должен решить проблему.

Также рассмотрите возможность сообщения об ошибке в Amazon.

Я сообщил об ошибке в SSH.NET включая необходимое изменение .


Если вы не можете изменить код SSH.NET, вам нужно будет использовать другую библиотеку SFTP.

Например, моя сборка WinSCP .NET совместима с управляемым Amazon 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 может сгенерировать шаблон кода , подобный приведенному выше для вас.

...