Как ответить «да» на ключевой вопрос кеша plink в С#

Я использую plink из С# для подключения к серверам Linux и запуска некоторых программ. И консольная программа С#, и plink.exe находятся на одном компьютере с Windows.

Проблема в том, что когда я впервые подключаюсь к серверу Linux, plink спрашивает меня, хочу ли я принять и сохранить ключ SSH с сервера Linux. Я всегда хочу ответить «да» на это, потому что все серверы находятся в моей локальной сети и нет проблем с безопасностью.

Я использую тип процесса С#, передаю правильный аргумент в plink, перенаправляю вывод и запускаю. Теперь проблема заключается в том, что когда запрашивает plink, process.StandardOutput.ReadToEnd(); зависает, и у меня нет возможности выяснить, предложил ли мне plink принять ключ или я действительно вошел на сервер Linux.

        string output = string.Empty;
        string error = string.Empty;
        string arguments = @" -ssh -pw password [email protected] ./Install_xxx.bin";

        using (Process process = new Process())
        {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = "plink";
            psi.Arguments = arguments;
            psi.ErrorDialog = false;
            psi.UseShellExecute = false;
            psi.RedirectStandardError = true;
            psi.RedirectStandardInput = true;
            psi.RedirectStandardOutput = true;
            psi.CreateNoWindow = true;

            process.StartInfo = psi;
            process.Start();

            output = process.StandardOutput.ReadToEnd();
            error = process.StandardError.ReadToEnd();
        }

Спасибо


person danze    schedule 17.03.2011    source источник


Ответы (3)


Ваша проблема с взаимоблокировкой описана в документе Process. . Когда процесс ожидает ввода, он не может закрыть стандартный ввод, поэтому он будет заблокирован. StandardOutput не будет закрыт, потому что процесс все еще ожидает вашего ввода со стандартного ввода: Deadlock. Вы можете либо использовать асинхронный API для чтения построчно, либо использовать для другого потока другой поток.

person Alois Kraus    schedule 17.03.2011
comment
Спасибо... Я решил использовать асинхронные методы. - person danze; 18.03.2011

Вместо использования внешнего исполняемого файла для подключения SSH, почему бы не использовать библиотеку SSH и сделать это (более надежно) через код?

sharpSsh (самая последняя версия здесь) — это порт C# Jsch, библиотеки Java под лицензией BSD. Я очень успешно использовал его в своих проектах на C#; вы сможете программно обрабатывать все аспекты SSH-соединения, включая согласование ключей.

person josh3736    schedule 17.03.2011
comment
Это был полезный ответ, потому что он привел меня к похожей, но более новой библиотеке SSH.NET. - person James Toomey; 04.12.2019

Для беспрепятственного подключения к удаленному серверу через PLINK в первый раз и в последующие разы вам необходимо вручную согласовать свои SSH-ключи. То есть используйте PUTTYGEN для создания файла закрытого ключа .ppk, который будет использовать PLINK, и заранее сохраните соответствующий открытый ключ в файле ~/.ssh/authorized_keys на сервере.

Вам также необходимо скоординировать ключи хоста sshd, поэтому используйте PUTTYGEN для создания набора файлов закрытых ключей ssh_host_rsa_key и ssh_host_dsa_key под /etc/ssh (посмотрите на существующие файлы, чтобы выяснить, в какие форматы ключей экспортировать), а затем запустите ssh-keygen -y -f /etc/ssh/ssh_host_rsa_key > /etc/ssh/ssh_host_rsa_key.pub, чтобы создать соответствующие файлы открытых ключей (сделайте то же самое, чтобы создать файл ssh_host_dsa_key.pub).

Если у вас есть несколько серверов, к которым вы хотите подключиться по PLINK, и вы не возражаете против использования одного и того же ключа для подключения ко всем из них (это будет зависеть от вашей локальной политики ИТ-безопасности), просто скопируйте одни и те же файлы ключей на каждый сервер. .

ЗАТЕМ на вашем компьютере с Windows, на котором вы используете PLINK, вручную подключитесь к любому серверу, используя PUTTY или PLINK, и в интерактивном режиме примите ключ хоста. Как только вы это сделаете, PUTTY/PLINK сохранит этот ключ в реестре Windows под HKCU\Software\SimonTatham\PuTTY\SshHostKeys. Вы заметите такую ​​запись, как rsa2@22:host, где host — это имя хоста вашего сервера.

Теперь, для сути процедуры, вам нужно скопировать шестнадцатеричное значение REG_SZ 0x23,... в ваше приложение C#, где вам придется вручную использовать классы Microsoft.Win32.RegistryKey, чтобы записать это значение для всех других серверов, использующих ту же схему именования rsa2@22:host, прежде чем вы оболочку в PLINK (считаете ли вы это значение реестра чувствительным к безопасности, зависит от вас, поэтому защитите его как-то в своем приложении C #, если вам нужно).

Как уже упоминалось, вы можете рассмотреть возможность использования библиотеки SSH, чтобы получить более программную обратную связь о вашем процессе подключения, но для использования PLINK это то, что вам нужно сделать.

person Erhhung    schedule 01.02.2012