WaltSteadman
MIS
Greetings all,
First and foremost, I am sorry for the long post, but I am stumped. I previously had a post about using Net::Telnet and Travs69 was a big help in getting me focused in on the problem and getting the script running. I guess what I am looking for is more assistance or a better method for doing what I am doing. I would love to see a good example of expect used with perl as I have heard that is really a better thing for interactive logins, but the documents on cpan don't show a very good example or I am just not the brighest bulb on the christmas tree.
I thought the Net::Telnet would work for logging into all the different device types we have here where I work. We use F5 Load Balancers, both Version 4.5 and Version 9 and I could not get it to work for either so I decided to use Net::SSH:
erl to log into the BigIPs and for the Version 4.5 it works well as it does not require Interactive Login but the Version 9 device requires interactive login.
My delimma is that I was not able to get Net::Telnet to work with Version 4.5, so I have not tried it with Version 9 and can't get Net::SSH:
erl to work with V9.
I did a debug with Net::SSH:
erl and I think the issue is with the interactive login requirement for the Version 9 device. I have added my code for Net::SSH:
erl portion of the script I am using. I can upload as much of my script as required, just didn't want to bog the post down with a long script. I did also place my Net::Telnet portion of the script that works great from my Netscreen FW and VPN devices.
Before I put in the script I have added the debugs for both the Version 4.5 and Version 9 connections. I think the issue comes in with the line for "Authentication methods that can continue"
as Version 9 says only publickey and keyboard-interactive
where Version 4.5 says publickey,password
Any assistance or pointers would be greatly appreciated. Been working on this portion of the script for a week and racking my brains on it.
Version 9 (Failed version)
Debug information:
#=================================
my.server.com: Reading configuration data /root/.ssh/config
my.server.com: Reading configuration data /etc/ssh_config
my.server.com: Allocated local port 1023.
my.server.com: Connecting to adcq5z36-bigip1a, port 22.
my.server.com: Remote version string: SSH-2.0-OpenSSH_4.5
my.server.com: Remote protocol version 2.0, remote software version OpenSSH_4.5
my.server.com: Net::SSH:
erl Version 1.30, protocol version 2.0.
my.server.com: No compat match: OpenSSH_4.5.
my.server.com: Connection established.
my.server.com: Sent key-exchange init (KEXINIT), wait response.
my.server.com: Algorithms, c->s: 3des-cbc hmac-sha1 none
my.server.com: Algorithms, s->c: 3des-cbc hmac-sha1 none
my.server.com: Entering Diffie-Hellman Group 1 key exchange.
my.server.com: Sent DH public key, waiting for reply.
my.server.com: Received host key, type 'ssh-dss'.
my.server.com: Host 'adcq5z36-bigip1a' is known and matches the host key.
my.server.com: Computing shared secret key.
my.server.com: Verifying server signature.
my.server.com: Waiting for NEWKEYS message.
my.server.com: Enabling incoming encryption/MAC/compression.
my.server.com: Send NEWKEYS, enable outgoing encryption/MAC/compression.
my.server.com: Sending request for user-authentication service.
my.server.com: Service accepted: ssh-userauth.
my.server.com: Trying empty user-authentication request.
my.server.com: Authentication methods that can continue: publickey,keyboard-interactive.
my.server.com: Next method to try is publickey.
<h1>Software error:</h1>
<pre>Permission denied at healthchecksubs.cgi line 161
VERSION 4.5 (WORKS)
#=========================
my.server.com: Reading configuration data /root/.ssh/config
my.server.com: Reading configuration data /etc/ssh_config
my.server.com: Allocated local port 1023.
my.server.com: Connecting to webbigip78, port 22.
my.server.com: Remote version string: SSH-1.99-OpenSSH_3.7.1p1
my.server.com: Remote protocol version 1.99, remote software version OpenSSH_3.7.1p1
my.server.com: Net::SSH:
erl Version 1.30, protocol version 2.0.
my.server.com: No compat match: OpenSSH_3.7.1p1.
my.server.com: Connection established.
my.server.com: Sent key-exchange init (KEXINIT), wait response.
my.server.com: Algorithms, c->s: 3des-cbc hmac-sha1 none
my.server.com: Algorithms, s->c: 3des-cbc hmac-sha1 none
my.server.com: Entering Diffie-Hellman Group 1 key exchange.
my.server.com: Sent DH public key, waiting for reply.
my.server.com: Received host key, type 'ssh-dss'.
my.server.com: Host 'webbigip78' is known and matches the host key.
my.server.com: Computing shared secret key.
my.server.com: Verifying server signature.
my.server.com: Waiting for NEWKEYS message.
my.server.com: Enabling incoming encryption/MAC/compression.
my.server.com: Send NEWKEYS, enable outgoing encryption/MAC/compression.
my.server.com: Sending request for user-authentication service.
my.server.com: Service accepted: ssh-userauth.
my.server.com: Trying empty user-authentication request.
my.server.com: Authentication methods that can continue: publickey,password.
my.server.com: Next method to try is publickey.
my.server.com: Next method to try is password.
my.server.com: Trying password authentication.
my.server.com: Login completed, opening dummy shell channel.
my.server.com: channel 0: new [client-session]
my.server.com: Requesting channel_open for channel 0.
my.server.com: channel 0: open confirm rwindow 0 rmax 32768
my.server.com: Got channel open confirmation, requesting shell.
my.server.com: Requesting service shell on channel 0.
my.server.com: channel 1: new [client-session]
my.server.com: Requesting channel_open for channel 1.
my.server.com: Entering interactive session.
Net::SSH:
erl portion of Script
Script
First and foremost, I am sorry for the long post, but I am stumped. I previously had a post about using Net::Telnet and Travs69 was a big help in getting me focused in on the problem and getting the script running. I guess what I am looking for is more assistance or a better method for doing what I am doing. I would love to see a good example of expect used with perl as I have heard that is really a better thing for interactive logins, but the documents on cpan don't show a very good example or I am just not the brighest bulb on the christmas tree.
I thought the Net::Telnet would work for logging into all the different device types we have here where I work. We use F5 Load Balancers, both Version 4.5 and Version 9 and I could not get it to work for either so I decided to use Net::SSH:
My delimma is that I was not able to get Net::Telnet to work with Version 4.5, so I have not tried it with Version 9 and can't get Net::SSH:
I did a debug with Net::SSH:
Before I put in the script I have added the debugs for both the Version 4.5 and Version 9 connections. I think the issue comes in with the line for "Authentication methods that can continue"
as Version 9 says only publickey and keyboard-interactive
where Version 4.5 says publickey,password
Any assistance or pointers would be greatly appreciated. Been working on this portion of the script for a week and racking my brains on it.
Version 9 (Failed version)
Debug information:
#=================================
my.server.com: Reading configuration data /root/.ssh/config
my.server.com: Reading configuration data /etc/ssh_config
my.server.com: Allocated local port 1023.
my.server.com: Connecting to adcq5z36-bigip1a, port 22.
my.server.com: Remote version string: SSH-2.0-OpenSSH_4.5
my.server.com: Remote protocol version 2.0, remote software version OpenSSH_4.5
my.server.com: Net::SSH:
my.server.com: No compat match: OpenSSH_4.5.
my.server.com: Connection established.
my.server.com: Sent key-exchange init (KEXINIT), wait response.
my.server.com: Algorithms, c->s: 3des-cbc hmac-sha1 none
my.server.com: Algorithms, s->c: 3des-cbc hmac-sha1 none
my.server.com: Entering Diffie-Hellman Group 1 key exchange.
my.server.com: Sent DH public key, waiting for reply.
my.server.com: Received host key, type 'ssh-dss'.
my.server.com: Host 'adcq5z36-bigip1a' is known and matches the host key.
my.server.com: Computing shared secret key.
my.server.com: Verifying server signature.
my.server.com: Waiting for NEWKEYS message.
my.server.com: Enabling incoming encryption/MAC/compression.
my.server.com: Send NEWKEYS, enable outgoing encryption/MAC/compression.
my.server.com: Sending request for user-authentication service.
my.server.com: Service accepted: ssh-userauth.
my.server.com: Trying empty user-authentication request.
my.server.com: Authentication methods that can continue: publickey,keyboard-interactive.
my.server.com: Next method to try is publickey.
<h1>Software error:</h1>
<pre>Permission denied at healthchecksubs.cgi line 161
VERSION 4.5 (WORKS)
#=========================
my.server.com: Reading configuration data /root/.ssh/config
my.server.com: Reading configuration data /etc/ssh_config
my.server.com: Allocated local port 1023.
my.server.com: Connecting to webbigip78, port 22.
my.server.com: Remote version string: SSH-1.99-OpenSSH_3.7.1p1
my.server.com: Remote protocol version 1.99, remote software version OpenSSH_3.7.1p1
my.server.com: Net::SSH:
my.server.com: No compat match: OpenSSH_3.7.1p1.
my.server.com: Connection established.
my.server.com: Sent key-exchange init (KEXINIT), wait response.
my.server.com: Algorithms, c->s: 3des-cbc hmac-sha1 none
my.server.com: Algorithms, s->c: 3des-cbc hmac-sha1 none
my.server.com: Entering Diffie-Hellman Group 1 key exchange.
my.server.com: Sent DH public key, waiting for reply.
my.server.com: Received host key, type 'ssh-dss'.
my.server.com: Host 'webbigip78' is known and matches the host key.
my.server.com: Computing shared secret key.
my.server.com: Verifying server signature.
my.server.com: Waiting for NEWKEYS message.
my.server.com: Enabling incoming encryption/MAC/compression.
my.server.com: Send NEWKEYS, enable outgoing encryption/MAC/compression.
my.server.com: Sending request for user-authentication service.
my.server.com: Service accepted: ssh-userauth.
my.server.com: Trying empty user-authentication request.
my.server.com: Authentication methods that can continue: publickey,password.
my.server.com: Next method to try is publickey.
my.server.com: Next method to try is password.
my.server.com: Trying password authentication.
my.server.com: Login completed, opening dummy shell channel.
my.server.com: channel 0: new [client-session]
my.server.com: Requesting channel_open for channel 0.
my.server.com: channel 0: open confirm rwindow 0 rmax 32768
my.server.com: Got channel open confirmation, requesting shell.
my.server.com: Requesting service shell on channel 0.
my.server.com: channel 1: new [client-session]
my.server.com: Requesting channel_open for channel 1.
my.server.com: Entering interactive session.
Net::SSH:
Code:
foreach $bigip (@bigips)
{
$session = Net::SSH::Perl-> new($bigip, protocol=>2, debug=>1);
$session -> login($biglog, $bigpwd);
($stdout) = $session -> cmd("b fo show");
if ($stdout =~ /ACTIVE/)
{
my @sbin = $session -> cmd("ps \-aux \| grep \/sbin\/proxyd");
print "<h4>$bigip</h4>\n";
print "<h4>PROXY STATUS</h4>";
print "$sbin[0]\n";
print "<h4>========== TOP 10 VIPS AND NODES ==========</h4>";
print "\n";
my @topten = $session -> cmd("bigtop -vips 10 -nodes 10 -conn -once");
print "$topten[0]";
print "\n";
print "====================================\n";
}
else
{
print "<h4>$bigip</h4>STANDBY DEVICE\n";
print "====================================\n";
}
$session -> cmd("exit");
}
Script
Code:
#!/usr/bin/perl -w
#print "Content-type: text/plain; charset=iso-8859-1\n\n";
require "cgi-lib.pl";
use Date::Calc qw(:all);
use Text::Wrap;
use CGI::Pretty qw/:standard :cgi-lib/;
use Getopt::Long;
use Net::Telnet;
use Net::SSH::Perl;
use CGI::Carp qw(fatalsToBrowser);
====== setup portion of script omitted to reduce lines =====
$username= 'myusername';
#($year,$month,$day) = Today();
#$date = join ('',Today());
$fwpwd='mypassword';
$bigpwd='mypassword';
$zone='zoneid';
$fwuid = '_fuid';
$biguid = '_buid';
$biglog = "$username$biguid";
$netscreenlog = "$username$fwuid";
@bigz7 = ("mydevice64","mydevice65","mydevice66","mydevice67","mydevice68","mydevice69","mydevice88","mydevice89");
@bigz9 = ("mydevice38","mydevice39","mydevice48","mydevice49");
@bigz15 =("mydevice78","mydevice79","mydevice80","mydevice81");
@fwz7 =("myfw71a","myfw71b");
@fwz9 =("myfw91a","myfw91b");
@fwz15 =("myfw151a","myfw151a");
@vpnz7 =("vpnz7-vpn-1","vpnz7-vpn-2");
@vpnz9 =("vpnz9-vpn-1","vpnz9-vpn-2");
@vpnz15 =("vpnz15-vpn-1","vpnz15-vpn-2");
if ($zone =~ /Z7/)
{
@bigips = @bigz7;
@firewalls = @fwz7;
@vpns = @vpnz7;
}
elsif ($zone =~ /Z9/)
{
@bigips = @bigz9;
@firewalls = @fwz9;
@vpns = @vpnz9;
}
elsif ($zone =~ /Z15/)
{
@bigips = @bigz15;
@firewalls = @fwz15;
@vpns = @vpnz15;
}
foreach $bigip (@bigips)
{
$session = Net::SSH::Perl-> new($bigip, protocol=>2, debug=>1);
$session -> login($biglog, $bigpwd);
($stdout) = $session -> cmd("b fo show");
if ($stdout =~ /ACTIVE/)
{
my @sbin = $session -> cmd("ps \-aux \| grep \/sbin\/proxyd");
print "<h4>$bigip</h4>\n";
print "<h4>PROXY STATUS</h4>";
print "$sbin[0]\n";
print "<h4>========== TOP 10 VIPS AND NODES ==========</h4>";
print "\n";
my @topten = $session -> cmd("bigtop -vips 10 -nodes 10 -conn -once");
print "$topten[0]";
print "\n";
print "====================================\n";
}
else
{
print "<h4>$bigip</h4>STANDBY DEVICE\n";
print "====================================\n";
}
$session -> cmd("exit");
}
foreach $firewall (@firewalls)
{
print $firewall;
print "\n";
}
foreach $vpn (@vpns)
{
my $ns_ssh = ConnectToVPN($netscreenlog, $fwpwd, $vpn);
if ($ns_ssh) {
$ns_ssh->cmd("set console page 0");
my @vpn_saact = $ns_ssh->cmd("get sa active");
## trim result
my $x = 0;
foreach (@vpn_saact) {
if ( $_ =~ /[Tt]otal/ ) {
$x = 1;
print uc "$_";
}
}
if ($x == 0) {
print "Couldn't find any ACTIVE SA on $vpn\n";
}
$ns_ssh->cmd("set console page 22");
$ns_ssh->close;
}
print "\n";
}
#===============================================================
#SUBS USED WITH NET::TELNET
sub ConnectToVPN {
my ($vpn_username, $vpn_password, $vpn_host) = @_;
my $vpn_prompt = '/-> $/';
## Start ssh program.
my $vpn_pty = &spawn("ssh", "-l", $vpn_username, $vpn_host);#, "-F", "/home/vpn/newvpncheck/config"); # spawn() defined below
## Create a Net::Telnet object to perform I/O on ssh's tty.
my $vpn_ssh = new Net::Telnet (-fhopen => $vpn_pty,
-prompt => $vpn_prompt,
-telnetmode => 0,
-cmd_remove_mode => 1,
-output_record_separator => "\n",
-output_log => '/var/[URL unfurl="true"]www/cgi-bin/healthdump_log.txt',[/URL]
-input_log => '/var/[URL unfurl="true"]www/cgi-bin/healthinput_log.txt'[/URL]
);
## Login to remote host.
## Catch key fingerprint and add it if we don't have it.
if ($vpn_ssh->waitfor(-match => '/yes/', -errmode => "return", -timeout => 5)) {
$vpn_ssh->print("yes");
}
my $vpn_test = $vpn_ssh->waitfor(-match => '/password: ?$/i',
-errmode => "return");
# or warn "problem connecting to $vpn_host: ";
## exit if we can't connect
if(!$vpn_test) { print "Couldn't connect to $vpn_host\n"; return; }
$vpn_ssh->print($vpn_password);
$vpn_test = $vpn_ssh->waitfor(-match => $vpn_ssh->prompt,
-errmode => "return")
or warn "login failed: ", $vpn_ssh->lastline;
if(!$vpn_test) { print "\nCouldn't connect to $vpn_host\n\n"; return; }
$vpn_ssh;
}
sub spawn {
my(@cmd) = @_;
my($pid, $pty, $tty, $tty_fd);
## Create a new pseudo terminal.
use IO::Pty ();
$pty = new IO::Pty or die $!;
## Execute the program in another process.
unless ($pid = fork) { # child process
die "problem spawning program: $!\n" unless defined $pid;
## Disassociate process from existing controlling terminal.
use POSIX ();
POSIX::setsid
or die "setsid failed: $!";
## Associate process with a new controlling terminal.
$pty->make_slave_controlling_terminal;
$tty = $pty->slave;
$tty_fd = $tty->fileno;
close $pty;
## Make stdio use the new controlling terminal.
open STDIN, "<&$tty_fd" or die $!;
open STDOUT, ">&$tty_fd" or die $!;
open STDERR, ">&STDOUT" or die $!;
close $tty;
## Execute requested program.
exec @cmd
or die "problem executing $cmd[0]\n";
} # end child process
$pty;
} # end sub spawn