http://www.perlmonks.org?node_id=1027022


in reply to Re: Net::SSH2 and Trapeze, in-band authentication
in thread Net::SSH2 and Trapeze, in-band authentication

Thanks for your input, I'll look into these things tomorrow morning. I am indeed running this on a Linux host so there should be plenty of tracing options available, and other ways to solve the problem. I've only done scripted ssh a few times against Linux and BSD-based systems before so I kinda got lost when the standard auth_* methods didn't work as they did before :-)

Update:

$ ssh -vvvv 10.10.8.128 OpenSSH_4.3p2, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug2: ssh_connect: needpriv 0 debug1: Connecting to 10.10.8.128 [10.10.8.128] port 22. debug1: Connection established. debug1: permanently_set_uid: 0/0 debug1: identity file /root/.ssh/identity type 1 debug3: Not a RSA1 key file /root/.ssh/id_rsa. debug2: key_type_from_name: unknown key type '-----BEGIN' debug3: key_read: missing keytype debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug3: key_read: missing whitespace debug2: key_type_from_name: unknown key type '-----END' debug3: key_read: missing keytype debug1: identity file /root/.ssh/id_rsa type 1 debug1: identity file /root/.ssh/id_dsa type -1 debug1: loaded 3 keys debug1: Remote protocol version 2.0, remote software version NOS-SSH_2 +.0 debug1: no match: NOS-SSH_2.0 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_4.3 debug2: fd 3 setting O_NONBLOCK debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha1,diffie-h +ellman-group14-sha1,diffie-hellman-group1-sha1 debug2: kex_parse_kexinit: ssh-rsa,ssh-dss debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,blowfish-cbc,cast128-cb +c,arcfour128,arcfour256,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@ly +sator.liu.se,aes128-ctr,aes192-ctr,aes256-ctr debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,blowfish-cbc,cast128-cb +c,arcfour128,arcfour256,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@ly +sator.liu.se,aes128-ctr,aes192-ctr,aes256-ctr debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripe +md160@openssh.com,hmac-sha1-96,hmac-md5-96 debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-ripe +md160@openssh.com,hmac-sha1-96,hmac-md5-96 debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib debug2: kex_parse_kexinit: debug2: kex_parse_kexinit: debug2: kex_parse_kexinit: first_kex_follows 0 debug2: kex_parse_kexinit: reserved 0 debug2: kex_parse_kexinit: diffie-hellman-group14-sha1,diffie-hellman- +group1-sha1 debug2: kex_parse_kexinit: ssh-rsa debug2: kex_parse_kexinit: 3des-cbc debug2: kex_parse_kexinit: 3des-cbc debug2: kex_parse_kexinit: hmac-sha1 debug2: kex_parse_kexinit: hmac-sha1 debug2: kex_parse_kexinit: none debug2: kex_parse_kexinit: none debug2: kex_parse_kexinit: debug2: kex_parse_kexinit: debug2: kex_parse_kexinit: first_kex_follows 0 debug2: kex_parse_kexinit: reserved 0 debug2: mac_init: found hmac-sha1 debug1: kex: server->client 3des-cbc hmac-sha1 none debug2: mac_init: found hmac-sha1 debug1: kex: client->server 3des-cbc hmac-sha1 none debug2: dh_gen_key: priv key bits set: 189/384 debug2: bits set: 1010/2048 debug1: sending SSH2_MSG_KEXDH_INIT debug1: expecting SSH2_MSG_KEXDH_REPLY debug3: check_host_in_hostfile: filename /root/.ssh/known_hosts debug3: check_host_in_hostfile: match line 91 debug1: Host '10.10.8.128' is known and matches the RSA host key. debug1: Found key in /root/.ssh/known_hosts:91 debug2: bits set: 1001/2048 debug1: ssh_rsa_verify: signature correct debug2: kex_derive_keys debug2: set_newkeys: mode 1 debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug2: set_newkeys: mode 0 debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug2: service_accept: ssh-userauth debug1: SSH2_MSG_SERVICE_ACCEPT received debug2: key: /root/.ssh/identity (0x9f70f88) debug2: key: /root/.ssh/id_rsa (0x9f70fa0) debug2: key: /root/.ssh/id_dsa ((nil)) debug1: Authentication succeeded (none). debug1: channel 0: new [client-session] debug3: ssh_session2_open: channel_new: 0 debug2: channel 0: send open debug1: Entering interactive session. debug2: callback start debug2: client_session2_setup: id 0 debug2: channel 0: request pty-req confirm 0 debug3: tty_make_modes: ospeed 38400 debug3: tty_make_modes: ispeed 38400 debug3: tty_make_modes: 1 3 debug3: tty_make_modes: 2 28 debug3: tty_make_modes: 3 127 debug3: tty_make_modes: 4 21 debug3: tty_make_modes: 5 4 debug3: tty_make_modes: 6 0 debug3: tty_make_modes: 7 0 debug3: tty_make_modes: 8 17 debug3: tty_make_modes: 9 19 debug3: tty_make_modes: 10 26 debug3: tty_make_modes: 12 18 debug3: tty_make_modes: 13 23 debug3: tty_make_modes: 14 22 debug3: tty_make_modes: 18 15 debug3: tty_make_modes: 30 0 debug3: tty_make_modes: 31 0 debug3: tty_make_modes: 32 0 debug3: tty_make_modes: 33 0 debug3: tty_make_modes: 34 0 debug3: tty_make_modes: 35 0 debug3: tty_make_modes: 36 1 debug3: tty_make_modes: 37 0 debug3: tty_make_modes: 38 1 debug3: tty_make_modes: 39 0 debug3: tty_make_modes: 40 0 debug3: tty_make_modes: 41 0 debug3: tty_make_modes: 50 1 debug3: tty_make_modes: 51 1 debug3: tty_make_modes: 52 0 debug3: tty_make_modes: 53 1 debug3: tty_make_modes: 54 1 debug3: tty_make_modes: 55 1 debug3: tty_make_modes: 56 0 debug3: tty_make_modes: 57 0 debug3: tty_make_modes: 58 0 debug3: tty_make_modes: 59 1 debug3: tty_make_modes: 60 1 debug3: tty_make_modes: 61 1 debug3: tty_make_modes: 62 0 debug3: tty_make_modes: 70 1 debug3: tty_make_modes: 71 0 debug3: tty_make_modes: 72 1 debug3: tty_make_modes: 73 0 debug3: tty_make_modes: 74 0 debug3: tty_make_modes: 75 0 debug3: tty_make_modes: 90 1 debug3: tty_make_modes: 91 1 debug3: tty_make_modes: 92 0 debug3: tty_make_modes: 93 0 debug1: Sending environment. debug3: Ignored env HOSTNAME debug3: Ignored env TERM debug3: Ignored env SHELL debug3: Ignored env HISTSIZE debug3: Ignored env SSH_CLIENT debug3: Ignored env SSH_TTY debug3: Ignored env USER debug3: Ignored env LS_COLORS debug3: Ignored env MAIL debug3: Ignored env PATH debug3: Ignored env WWW_HOME debug3: Ignored env INPUTRC debug3: Ignored env PWD debug1: Sending env LANG = en_US.UTF-8 debug2: channel 0: request env confirm 0 debug3: Ignored env PS1 debug3: Ignored env SHLVL debug3: Ignored env HOME debug3: Ignored env LOGNAME debug3: Ignored env SSH_CONNECTION debug3: Ignored env LESSOPEN debug3: Ignored env G_BROKEN_FILENAMES debug3: Ignored env _ debug2: channel 0: request shell confirm 0 debug2: fd 3 setting TCP_NODELAY debug2: callback done debug2: channel 0: open confirm rwindow 1048576 rmax 16384 Copyright (c) 2002 - 2012 Juniper Networks, Inc. All rights reserved. Username:

Now... This isn't exactly my field of expertice but I notice the following, which I will need to emulate:

debug1: Authentication succeeded (none). debug1: channel 0: new [client-session] debug3: ssh_session2_open: channel_new: 0 debug2: channel 0: send open debug1: Entering interactive session.

So, as per your suggestion I tried $chan->shell() and it seems to have brought me one step further. $chan->read() now produces the following debug output: - read -37 bytes After a little bit more experimentation, I have rewritten my script slightly and arrived at the following slightly hackish but fully working solution:

#!/usr/bin/perl use strict; use warnings; use Carp; use Net::SSH2; my %hosts = ( "MX200-1" => "10.10.8.128" ); my $DEBUG = 1; foreach my $name (sort keys %hosts) { my $ip = $hosts{$name}; $DEBUG && print "check $name ($ip)\n"; my $ssh2 = Net::SSH2->new(); if ($ssh2->connect($ip)) { $DEBUG && print "connected\n"; $ssh2->debug($DEBUG); $DEBUG && print "version=".join(', ', $ssh2->version())."\n"; $DEBUG && print "error=".$ssh2->error()."\n"; $ssh2->auth_list(); # Returns undef, auth_ok() will return 0 unles +s we call this(?) if ($ssh2->auth_ok()) { # Returns 4 (= true, we have been authenti +cated OK) $DEBUG && print "authenticated ok\n"; if (my $chan = $ssh2->channel()) { $DEBUG && print "channel open\n"; $chan->shell(); $chan->blocking(0); print $chan "admin\n"; print $chan "********\n"; # Password print $chan "enable\n"; print $chan "********\n"; # Enable password print get_response($chan); print $chan "set length 0\n"; print get_response($chan); print $chan "show configuration\n"; print get_response($chan); $chan->close; $DEBUG && print "done\n"; } else { croak "Error opening channel"; } } else { croak "Expected to be authenticated: ".$ssh2->auth_ok()."\n"; } $ssh2->disconnect; } else { warn "Error connecting to $name ($ip); please check host status\n" +; } } sub get_response { my $chan = shift; my $res = ""; until ($res =~ /^\S+\#\s$/m) { # Keep reading until we see what look +s like a prompt $res .= get_channel($chan); $DEBUG && print "res='$res'\n"; } return $res; } sub get_channel { my $chan = shift; my $output = ""; my $bytes = -1; until ($chan->eof || !defined $bytes) { $bytes = $chan->read(my $buffer, 1024); # Blocks unless we set $ch +an->blocking(0) $DEBUG && print "bytes=".($bytes || 'undef')."\n"; if (defined $bytes) { $DEBUG && print "buffer=$buffer\n"; $output .= $buffer; } } return $output; }

-- Time flies when you don't know what you're doing

Replies are listed 'Best First'.
Re^3: Net::SSH2 and Trapeze, in-band authentication
by salva (Canon) on Apr 05, 2013 at 08:18 UTC
    I don't think the get_channel sub is reliable. If for whatever reason the data coming from the remote side is delayed, the non-blocking read call is going to return undef and any additional data will be lost.

    Doing non-blocking IO with Net::SSH2 is far from being easy. You can see how it is done in my module Net::SSH::Any using select to check when new data arrives on the SSH socket (the code is here, see the __io3 method).

    Another possibility that usually works is to send all the input data (login and commands) in one go and then capture everything in blocking mode until you get and EOF. You will have to add an additional command to close the connection from the remote side (i.e. exit).

      Yes, the data is indeed delayed and the non-blocking call does return undef every now and then. This is why I call get_channel() repeatedly from get_response() and accumulate the results until I see the prompt.

      The reason I can't do blocking calls is because the channel will never EOF or return a short buffer unless I tell the host to "exit" and terminate the connection. Not cool if I want to execute more commands based on the output from a previous command.

      -- Time flies when you don't know what you're doing