Re: Problems with Net::OpenSSH
by Khen1950fx (Canon) on Nov 23, 2010 at 07:52 UTC
|
Try this. It prompts for a password. It returns true if correct or "Permission denied" if incorrect.
#!/usr/bin/perl
use strict;
no warnings;
use Expect;
use Net::OpenSSH;
select STDOUT;
$| = 1;
select STDERR;
$| = 1;
my $username = 'root';
my $password = $ARGV;
my $ip = 'localhost';
my $timeout = 10;
my $debug = 0;
my $ssh = Net::OpenSSH->new( "$username\@$ip",
strict_mode => 0 );
my ( $pty, $pid ) = $ssh->open2pty("show ip arp")
or die "unable to run remote command show ip arp";
my $expect = Expect->init($pty);
$expect->raw_pty(1);
$debug and $expect->log_user(1);
$debug and print "waiting for password prompt\n";
$expect->expect( $timeout, ":" )
or die "expect failed, $expect->exp_error()\n";
$expect->send("$password\n");
while (<$pty>) {
print "$. $_";
}
| [reply] [d/l] |
|
|
andy@andy-desktop:~/core/arpinfo$ ./test2.pl
Password:
Password:
expect failed, Expect=GLOB(0x2083bb8)->exp_error()
Connection to 10.105.0.62 closed by remote host.
| [reply] [d/l] |
Re: Problems with Net::OpenSSH
by chrestomanci (Priest) on Nov 23, 2010 at 09:22 UTC
|
Will your router accept a public/private key pair for authentication instead of using password based auth?
A few years ago, I was controling a netapp storage device from perl, and I found that it would maintain a list of authorised public ssh keys. Once I had added my public key to it's keyring, I could then have my perl script connect using a private key, and without the need to handle password prompts. The connection went directly to a shell where typicaly my script would issue one command, capture the output and then dissconnect. This made that part of the script much simpler.
One issue to be aware of, is that the device I was connecting to did not like it if there was an SSH agent which offered several different keys until one was accepted. If the first key offered was not acceptable the connection got dropped, there was no possibility to try a different key or drop back to password based authentication, so when you test, you should add -a to your ssh command line.
| [reply] [d/l] |
|
|
| [reply] |
|
|
| [reply] |
Re: Problems with Net::OpenSSH
by salva (Canon) on Nov 23, 2010 at 08:42 UTC
|
As Anonymous Monk has already told you, the login phase is managed by the module and what you get from open2pty is not the login prompt but a shell on the remote device.
Anyway, usually, the following hack works:
my $ssh = Net::OpenSSH->new("$username:$password\@$ip", timeout => 30)
+;
$ssh->error and die "unable to connect to remote host: ". $ssh->error;
my $out = $ssh->capture({stdin_data => "show ip arp\n"});
It just starts a remote shell, pipes the command through its stdin and captures the output.
If that doesn't work, you will have to revert to Expect. Running the following one-liner from the command line will allow you to interact with the remote shell as returned by open2pty so you can experiment with it and see what you should expect.
perl -MNet::OpenSSH -e 'Net::OpenSSH->new(q(USER:PASSWD@HOST))->system
+({tty=>1})'
| [reply] [d/l] [select] |
|
|
andy@andy-desktop:~/core/arpinfo$ ./test3.pl
^C
NetServ_Lab_SW_2#show ip arp
Protocol Address Age (min) Hardware Addr Type Interface
Internet 4.2.4.1 - 0016.c859.1b41 ARPA Vlan42
Internet 192.168.120.1 - 0016.c859.1b42 ARPA Vlan499
...
...
NetServ_Lab_SW_2#
NetServ_Lab_SW_2#andy@andy-desktop:~/core/arpinfo$
| [reply] [d/l] |
|
|
Is there any command you can send the remote box to close the session?
For instance:
my $out = $ssh->capture({stdin_data => "show ip arp\nexit\n"});
| [reply] [d/l] |
Re: Problems with Net::OpenSSH
by Anonymous Monk on Nov 22, 2010 at 22:49 UTC
|
I see when you're initializing Net::OpenSSH, you are giving it the username and password there.
Is it possible that bypasses the password prompt (or makes Net::OpenSSH hide it from you) and just drops you at the command line one you are connected and authenticated? | [reply] |
|
|
#!/usr/bin/perl
use strict;
use warnings;
use Net::OpenSSH;
use Expect;
$| = 1;
my $username = '';
my $password = '';
my $enable = '';
my $ip = '10.105.0.62';
my $ssh = Net::OpenSSH->new("$username:$password\@$ip", timeout => 30)
+;
$ssh->error and die "unable to connect to remote host: ". $ssh->error;
my ($pty, $pid) = $ssh->open2pty("show ip arp")
or die "unable to run remote command show ip arp";
my $expect = Expect->init($pty);
$expect->raw_pty(1);
#$expect->debug(2);
my $debug and $expect->log_stdout(1);
while(<$pty>) {
print "$. $_"
}
| [reply] [d/l] |
|
|
But your router seems to support commands from SSH without dropping you to the shell. You probably don't need to use Expect at all:
#!/usr/bin/perl
use strict;
use warnings;
use Net::OpenSSH;
$| = 1;
my $username = '';
my $password = '';
my $enable = '';
my $ip = '10.105.0.62';
my $ssh = Net::OpenSSH->new("$username:$password\@$ip", timeout => 30)
+;
$ssh->error and die "unable to connect to remote host: ". $ssh->error;
my $out = $ssh->pipe_out("show ip arp")
or die "unable to run remote command show ip arp";
while(<$out>) {
print "$. $_"
}
| [reply] [d/l] |
Re: Problems with Net::OpenSSH
by pklausner (Scribe) on Nov 23, 2010 at 14:49 UTC
|
If you control many Ciscos, you should consider running Rancid anyway.
That comes with clogin, which does what you want.
(Caveat: Rancid mixes Perl, sh & expect/tcl) | [reply] |
|
|
I use rancid for config gathering among other things for the Cisco side of the network here. I think for what I am trying to do it would be more of a headache to try to tie in Rancid. I am in the middle of a large network redesign and am trying to gather and correlate data; NAT, Layer3 ARP, Layer2 MAC, VRRP/HSRP/GLBP and a handful of other things all living on F5, Cisco, Foundry/Brocade, Juniper, Radware, Extreme, and Secure Computing. Most of these devices are unsupported in RANCID. I thought about it and then realized it might just be easier to start from scratch. No I am not stretching the truth... We really do have that many different vendors in our network. Anyone have an easy button? :)
| [reply] |