Net::OpenSSH не запускает команду?

Я пытаюсь начать использовать модуль Net::OpenSSH и столкнулся с проблемами. Я попробовал несколько разных методов, которые нашел в Интернете, но, похоже, мне не удалось получить выходные данные команды на удаленном устройстве (в данном случае маршрутизаторах Nokia).

Я вижу «сообщение» для входа (предупреждение о несанкционированном доступе и т. д.) при подключении, но не вижу никаких запросов на вход (должны ли они быть видны с помощью Net::OpenSSH?).

Затем я вижу это сообщение «Соединение с удаленным хостом закрыто».

Я не могу сказать, что он делает, поскольку он больше ничего не выводит на экран и не заполняет $fh. Есть идеи?

#!/usr/bin/perl

use strict;
use warnings;

use Net::OpenSSH;
my $ip = "";
my $username = "";
my $passwd = "";

            my $ssh = connect_to_device($ip);
            my $fh = $ssh->pipe_out('show card state') or die "unable to run command\n";
            while (<$fh>) {
                    print "$_";  
            }
            close $fh;
            undef $ssh;
    
    sub connect_to_device {
            my $deviceIpAddr = shift;
            $Net::OpenSSH::debug = ~0;  # Enable comprehensive debug output
            my $ssh = Net::OpenSSH->new($deviceIpAddr,
                    user => $username,
                    password => $passwd,
                    timeout => 3,
                    strict_mode => 0,
                    master_opts => ['-o UserKnownHostsFile=/dev/null']
            );
            $ssh->error and die "Couldn't establish SSH connection: ". $ssh->error;
            return $ssh;
    }

Отладочный вывод:

# open_ex: ['ssh','-V']
# io3 mloop, cin: 0, cout: 1, cerr: 0
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 48 at offset 0
#> 4f 70 65 6e 53 53 48 5f 37 2e 34 70 31 2c 20 4f 70 65 6e 53 53 4c 20 31 2e 30 2e 32 6b 2d 66 69 | OpenSSH_7.4p1, OpenSSL 1.0.2k-fi
#> 70 73 20 20 32 36 20 4a 61 6e 20 32 30 31 37 0a                                                 | ps  26 Jan 2017.
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 0 at offset 48
# leaving _io3()
# _waitpid(14149) => pid: 14149, rc: 0, err: 
# OpenSSH version is 7.4p1,
# ctl_path: /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, ctl_dir: /root/.libnet-openssh-perl/
# set_error(0 - 0)
# call args: ['ssh','-o UserKnownHostsFile=/dev/null','-o','ServerAliveInterval=10','-o','ControlPersist=no','-2MNx','-o','NumberOfPasswordPrompts=1','-o','PreferredAuthentications=keyboard-interactive,password','-S','/root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad','-l','<username>','<ipaddress>','--']
# master state jumping from _STATE_START to _STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# tracer attached, ssh pid: 14150, tracer pid: 14151
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
Warning: Permanently added '<ipaddress>' (RSA) to the list of known hosts.
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
TiMOS-C-16.0.R11 cpm/hops64 Nokia 7450 ESS Copyright (c) 2000-2020 Nokia.
All rights reserved. All use subject to applicable license agreements.
Built on Wed Jan 29 11:57:40 PST 2020 by builder in /builds/c/160B/R11/panos/main
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_LOGIN
# passwd/passphrase requested (<username>@<ipaddress>'s password:)
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_AWAITING_MUX
# file object not yet found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad, state:_STATE_AWAITING_MUX
# file object found at /root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad
# master state jumping from _STATE_AWAITING_MUX to _STATE_RUNNING
# call args: ['ssh','-O','check','-T','-S','/root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad','-l','<username>@<ipaddress>','--']
# open_ex: ['ssh','-O','check','-T','-S','/root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad','-l','<username>@<ipaddress>','--']
# io3 mloop, cin: 0, cout: 1, cerr: 0
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 28 at offset 0
#> 4d 61 73 74 65 72 20 72 75 6e 6e 69 6e 67 20 28 70 69 64 3d 31 34 31 35 30 29 0d 0a             | Master running (pid=14150)..
# io3 fast, cin: 0, cout: 1, cerr: 0
# stdout, bytes read: 0 at offset 28
# leaving _io3()
# _waitpid(14161) => pid: 14161, rc: 0, err: 
# call args: ['ssh','-S','/root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad','-l','<username>@<ipaddress>','--','show card state']
# pipe_out: 'ssh''-S''/root/.libnet-openssh-perl/7d29d81a517f00787fb9ba9ca54353ad''-l''<username>@<ipaddress>''--''show card state'
Connection to <ipaddress> closed by remote host.
# DESTROY(Net::OpenSSH=HASH(0xd7fd58), pid: 14150)
# sending exit control to master
# set_error(1 - control command failed: master SSH connection broken)
# master state jumping from _STATE_RUNNING to _STATE_KILLING
# killing master
# _master_kill: 14150
# waitpid(master: 14150) => pid: 0, rc: No such file or directory
# waitpid(master: 14150) => pid: 14150, rc: Interrupted system call
# master state jumping from _STATE_KILLING to _STATE_GONE
# master state jumping from _STATE_GONE to _STATE_GONE

В вашем сабе $username и $passw не определены. Пожалуйста, покажите полный минимальный пример. См. минимальный воспроизводимый пример для получения дополнительной информации.

Håkon Hægland 28.06.2024 23:40

Они определены глобально.

Jason M 01.07.2024 14:22

должны ли они быть видимы с помощью Net::OpenSSH?" : Я не думаю, что вы должны что-то видеть, если Net::OpenSSH->new() успешен. Можете ли вы попробовать включить вывод отладки? Кроме того, можете ли вы успешно подключиться из оболочки, используя ssh user@ip_addr?

Håkon Hægland 01.07.2024 15:09

Я могу подключиться через обычный SSH (с сервера, который я использую, или напрямую с моего компьютера) и через другие сценарии, использующие Net::SSH:Expect. Этот новый тест предназначен для того, чтобы попытаться заставить Net::OpenSSH работать. Я считаю, что этот сценарий подключается, но после этого что-то, похоже, не работает.

Jason M 02.07.2024 16:05

# аргументы вызова: ['ssh','-S','/root/.libnet-openssh-perl/7d29d81a517f00787fb9‌​ba9ca54353ad','-l','‌​<имя пользователя>@<ipaddres‌​s>', '--','показать состояние карты']" Что означает "показать состояние карты" в выводе отладки?

Håkon Hægland 05.07.2024 18:39

«показать состояние карты» — это команда, которую нужно запустить на устройстве.

Jason M 05.07.2024 19:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы отладить это, попробуйте включить отладочный вывод из Net::OpenSSH. Например:

use v5.38;
use Net::OpenSSH;

$Net::OpenSSH::debug = ~0;  # Enable comprehensive debug output
my $user = "hakonh";
my $host = "172.17.0.2";
my $port = 2222;
my $ssh = Net::OpenSSH->new(
    $host,
    user => $user,
    port => $port,
    passwd => '????'
);
$ssh->error and
  die "Couldn't establish SSH connection: ". $ssh->error;

say "Successfully connected ";

# Shut down the connection by letting the `$ssh` object go out of scope

Пожалуйста, обновите свой вопрос, указав такие отладочные данные. Это может помочь нам сузить проблему.

Я опубликовал вывод отладки

Jason M 05.07.2024 18:26

@JasonM Спасибо, также обновите вопрос, указав точный сценарий, который вы использовали для создания отладочных результатов.

Håkon Hægland 05.07.2024 18:37

Обновил его дополнительной строкой отладки.

Jason M 05.07.2024 18:48

Спасибо за обновление. Так вот эта строка не работает: my $fh = $ssh->pipe_out('show card state') or die "unable to run command\n"? Можете ли вы это проверить?

Håkon Hægland 05.07.2024 18:50

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

Jason M 05.07.2024 18:53

Вместо этого: $ssh->pipe_out('show card state') попробуйте создать такой массив my $fh = $ssh->pipe_out('show', 'card', 'state')

Håkon Hægland 05.07.2024 18:58

Я поменял местами эту строку, и вывод отладки выглядит идентичным. Даже та часть, где показаны строки «call args» и «pipe_out», выглядят одинаково. И до сих пор нет вывода команды.

Jason M 05.07.2024 19:21

Что произойдет, если вместо этого вы запустите стандартную команду, например «echo»? Пример: my $pipe = $ssh->pipe_out('echo', '1', '2');

Håkon Hægland 05.07.2024 19:23

Никакой разницы, по-прежнему нет вывода команды. Я попробовал довольно много команд разных типов, и у всех одна и та же проблема.

Jason M 05.07.2024 19:26

А если удалить $ssh->pipe_out() и следующие 4 строки, в которых используется $fh? Вы все еще получаете ошибки?

Håkon Hægland 05.07.2024 19:28

В любом случае я не получаю ошибок, просто нет вывода команды. Если я оставлю эти линии вне поля, единственная разница в том, что они то соединяются, то отключаются.

Jason M 05.07.2024 19:31

Хорошо, хорошо, значит, проблема в выводе? Когда вы запускаете ssh из оболочки, вы получаете результат?

Håkon Hægland 05.07.2024 19:33

Да, все работает нормально, если я подключаюсь к устройству напрямую из оболочки или Securecrt. Это также отлично работает, если я использую «net::ssh::expect», а не net::openssh.

Jason M 05.07.2024 19:35

Давайте проверим, не является ли проблема командой pipe(): если вы запустите «ls» на пульте дистанционного управления, вы получите вывод? В скрипте вы можете попробовать использовать команду system(): Пример: $ssh->system("ls") or die "remote command failed: " . $ssh->error;

Håkon Hægland 05.07.2024 19:37

ls не является допустимой командой на удаленном устройстве, но я и раньше пробовал «систему». В отладке единственная разница в том, что это «open_ex» вместо «pipe_out» # open_ex: ['ssh','- S','/root/.libnet-openssh-perl/a3610065525649864c26‌​673faadc75b5','-l','‌​<имя пользователя>','<ipaddr‌​ess>','--','показать состояние карты' ]

Jason M 05.07.2024 19:39

Вы пробовали использовать «показать», «карту», ​​«состояние» (3 аргумента), а не «показать состояние карты» (один аргумент)? Пример: my ($in, $out, $err, $pid) = $ssh->open_ex('show', 'card', 'state'); print "out = $out\n"

Håkon Hægland 05.07.2024 19:44

Я так пробовал, разницы нет.

Jason M 05.07.2024 19:51

Может быть, попробовать получить больше отладочных данных от самого ssh, передав master_opts => ['-vvv'] вызову Net::OpenSSH->new()?

Håkon Hægland 05.07.2024 20:09

Вы также можете попытаться определить, связана ли проблема с ssh-сервером маршрутизаторов Nokia, запустив ее на других ssh-серверах.

Håkon Hægland 05.07.2024 20:12

У меня нет другого устройства, отличного от Nokia, к которому можно было бы подключиться по SSH отсюда. Когда я использую «-vvv», я вижу, что он проходит аутентификацию, и вижу, что он пытается отправить команду, которую я предоставляю, но я не получаю ни ошибки, ни какого-либо вывода.

Jason M 05.07.2024 20:26

Поскольку Net::OpenSSH — это всего лишь оболочка для команды ssh, а ssh работает с терминала. Я бы также проверил это -vvv в терминале и проверил, что вы передаете точно те же аргументы, которые показывает -vvv в Perl-скрипте.

Håkon Hægland 05.07.2024 20:29

В качестве теста я попытался указать сценарию запустить «интерактивный режим», добавив эту строку $ssh->system; Он вошел в систему и вывел меня в командную строку устройства, хотя и не пытался выполнить команду. Для такого взаимодействия может потребоваться использование «ожидания» или чего-то подобного. По крайней мере, это говорит мне о том, что вход в систему действительно работает (подтверждая то, что я вижу в журналах), но что-то заставляет его «отключаться» при использовании любого из вариантов отправки команды (system, capture, capture2, Pipe_out). Не уверен, что с этим делать. Это

Jason M 05.07.2024 20:31

См. раздел «Подключение к свитчам, роутерам и т.п.». в FAQ: Metacpan.org/pod/Net::OpenSSH#FAQ : ".... Лучшим инструментом для этой задачи, вероятно, является Expect, используемый отдельно или в сочетании с Net::OpenSSH"

Håkon Hægland 05.07.2024 20:38

Я рассмотрю возможность использования openssh+expect. Возможно, это единственный вариант, поскольку более прямой метод не работает с этими устройствами. Я ценю вашу помощь в этом.

Jason M 05.07.2024 21:13

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