Windows 上的 OpenSSH 服务器即使在非交互模式下,如果没有 STDIN 也无法工作

Windows 上的 OpenSSH 服务器即使在非交互模式下,如果没有 STDIN 也无法工作

(相关这个问题

使用 sshd 服务器时(Win32的OpenSSH) 在 Windows 上(使用基于密钥的身份验证进行自动化),除非有 STDIN(或 PTY),否则它不起作用。例如,运行此命令(从 Debian Jessie openssh 客户端)可以正常工作(返回 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

这会带来问题,因为无法从没有打开 STDIN 的程序(例如cron(8)或者艾滋病毒(8))。

使用 Debian openssh 服务器时,它当然可以正常工作。问题只发生在 windows ssh 服务器上(失败Win32的OpenSSH自由SSHDBitvise SSHD但是似乎工作正常,但我们正在寻找适用于 Windows ssh 服务器的免费解决方案;开源、简单和维护是优势)

这已经已报告,但与此同时有人有解决方案或解决方法吗?

答案1

最后,我编写了这个 ssh 包装器来解决有缺陷的 Windows OpenSSH 服务器,这些服务器甚至对于不使用 STDIN 的非交互式命令也需要 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)艾滋病毒(8)

答案2

感谢 Matija-Nalis 提出的问题和解决方案。为了其他人的利益,这里有一个粗略的 Python 实现。

ssh工具

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>

我的用例类似:詹金斯作业无法执行远程命令。

相关内容