Сервер OpenSSH на Windows отказывается работать без STDIN даже в неинтерактивном режиме

(относится к этому вопросу)

При использовании сервера sshd ( Win32-OpenSSH) в Windows (с аутентификацией на основе ключей для автоматизации) он не работает, если у него нет STDIN (или PTY). Например, выполнение этого (из openssh-клиента Debian Jessie) работает нормально (возвращая имя пользователя windows):

ssh -4 -T -o Batchmode=yes winserver whoami

Тем не менее, эти два не (они просто завершены без выполнения команды и без возврата какого-либо вывода):

ssh -4 -T -o Batchmode=yes winserver whoami < /dev/null
ssh -4 -n -T -o Batchmode=yes winserver whoami

Это создает проблему, поскольку невозможно запускать неинтерактивные команды ssh из программ, которые не имеют открытого STDIN (например, cron (8) или atd (8)).

При использовании сервера Debian OpenSSH, он, конечно, работает без проблем. Проблема возникает только с серверами Windows SSH (Сбой с Win32-OpenSSH и FreeSSHD. Однако Bitvise SSHD, кажется, работает нормально, но мы смотрим на бесплатные решения для серверов Windows SSH; открытые, простые и поддерживаемые бонусы)

Об этом сообщалось, но есть ли у кого-нибудь решение или обходной путь в то же время?

2 ответа

Решение

В конце я написал эту оболочку ssh для работы с ошибочными серверами OpenSSH с Windows, которые требуют STDIN даже для неинтерактивных команд, которые его не используют:

#!/usr/bin/perl

use strict;
use warnings;
use Net::OpenSSH;

my $HOSTNAME = shift;
my $ssh = Net::OpenSSH->new($HOSTNAME);

my ($in_pipe, undef, undef, $pid) =
    $ssh->open_ex( { stdin_pipe => 1 }, @ARGV) or die "open_ex failed: " . $ssh->error;

waitpid($pid, 0);

Он использует только имя хоста и команду с аргументами для запуска, другие параметры не разрешены (я установил их в ~/.ssh/config), поэтому вы запускаете скрипт (например) как myssh winserver whoami < /dev/null, Это просто оболочка для клиента ssh, которая предоставляет поддельный STDIN и, таким образом, позволяет запускать неинтерактивные сеансы ssh из cron(8) и atd(8).

Спасибо Матия-Налис за вопрос и решение. Для получения выгоды, вот грубая реализация Python.

ssh.py

import sys
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(sys.argv[2], username=sys.argv[1])
stdin, stdout, stderr = client.exec_command(sys.argv[3])
errlines = stderr.readlines()
outlines = stdout.readlines()
for l in outlines:
    print l.rstrip()
if len(errlines):
    print "WARNING: stderr generated:"
    for l in errlines:
        print l.rstrip()
exit(stdout.channel.recv_exit_status())

python ssh.py <user> <hostname> <command>

Мой пример использования был аналогичным: заданию Jenkins не удалось выполнить удаленные команды.

Другие вопросы по тегам