I have a perl script starts an EC2 instance and then uses Net::OpenSSH to connect and run some commands.
my $ssh = Net::OpenSSH->new( $username . "\#" . $host,
key_path => $key_path,
master_opts => [-o => "ConnectionAttempts=30", -o => "ConnectTimeout=30"] );
if ( $ssh->error ) {
die "Timeout: " . $ssh->error . "\n";
}
This doesn't appear to be working - this should try for 15 minutes, and then quit, but it returns almost immediately. I never get the Timeout: error message, so ssh is not returning an error.
Is this the correct syntax? Is there a better way to deal with the fact that the EC2 instance may take a few minutes before it is available?
As per CPAN documentation I can see that ConnectionAttempts and ConnectTimeout should go to default_ssh_opts instead of master_opts. Please try that out.
Related
I am running moss by Stanford.
I am using Perl script sent by Stanford at the time of registration.
but it is giving error as :
Checking files . . .
OK
Could not connect to server moss.stanford.edu: Connection refused
I tried adding institute proxy also in the code as follows :
$sock = new IO::Socket::INET (
ProxyAddr => '10.3.100.207',
ProxyPort => '8080',
PeerAddr => $server,
PeerPort => $port,
Proto => 'tcp',
);
But it is giving the same error as above.
One possible solution is to set up a virtual environment and run the script.
But what can be another solution ?
Here is what I did and it worked.
I used Google colab for it.
I uploaded the files to be checked for plagiarism and the perl script to colab and then ran the perl script in the notebook
!perl moss.pl -l python -m 53 -c "Files" ./*.py
I have problem with perl modules, i 'm trying to connect to the remote server using the OpenSSH module from CPAN and i have given the username and password correctly but when i run my CGI from browser i see the following error message "
can't ssh:unable to establish master SSH connection: bad password or
master process exited unexpectedly
in need of immediate reply's and awaiting,
Thanks in Advance.
Here is my code
#!/usr/bin/perl -w
use CGI;
use Data::Dumper;
use strict;
use CGI::Carp qw(fatalsToBrowser);
use Net::OpenSSH;
my $query = CGI->new();
#my $mach_name=$query->param('mach_name');
my $mach_name= '****.cce.***.com';
my $user='root';
my $passwd='*******';
my $ssh = Net::OpenSSH->new("$mach_name",user => "$user" , passwd => "$passwd
", master_opts => [-o => "strictHostKeyChecking=no"]);
$ssh->error and die "can't ssh:" . $ssh->error;
my $mem_info =$ssh->capture("ioscan -m lun");
print "$mem_info";
print "Content-type: text/html\n\n";
print "<html><head><title>test page</title></head>\n";
print "<body><p>Dicovering Machine Please wait....</p>\n";
print "<p>$mach_name</p>";
print "<p><b>Swap Memory :$mem_info </b> </p>";
print "</body></html>";
The same program if i run through the command line it is getting the o/p but through the browser i'm seeing the above error i have given the passwd and username correctly
My problem was solved when I've increased the timeout from 10 seconds to 15 seconds, because the device is using an older SSH daemon version, but my linux server that made the client connection is upgraded and of course it probes first the newer ciphers.
my $ssh = Net::OpenSSH->new(
$host,
port => $port,
user => $user,
password => $pass,
timeout => 15, # <= this was 10 and now is 15
kill_ssh_on_timeout => 1,
strict_mode => 0,
master_opts => [-o => "StrictHostKeyChecking=no", '-vvv'], #<= -vvv helped much
ctl_dir =>'/tmp/libnet-openssh-perl',
Looks like some permissions issue. Run ssh in verbose mode:
my $ssh = Net::OpenSSH->new("$mach_name",
user => "$user",
passwd => "$passwd",
master_opts => '-vvv',
master_stderr_fh => \*LOG);
If that doesn't give you enough information about the cause of the problem, then, you can use truss to see what's happening at the OS level.
Also check .ssh/known_hosts, make sure .ssh directory is writeable by Apache. .libnet-openssh-perl directory should be writeable by Apache.
For example, my Apache user is apache with a home directory of /var/www
I have /var/www/.ssh owned by apache, and /var/www/.libnet-openssh-perl owned by apache. I ssh to devices using my own account, then copy my known_hosts file to /var/www/.ssh/known_hosts
Solution
As reported by #limulus in the answer I accepted, this was a bug in Net::HTTPS version 6.00. Always be wary of fresh .0 releases. Here's the relevant diff between the buggy and fixed version of that module:
D:\Opt\Perl512.32 :: diff lib\Net\HTTPS.pm site\lib\Net\HTTPS.pm
6c6
< $VERSION = "6.00";
---
> $VERSION = "6.02";
75,78c75,80
< # The underlying SSLeay classes fails to work if the socket is
< # placed in non-blocking mode. This override of the blocking
< # method makes sure it stays the way it was created.
< sub blocking { } # noop
---
> if ($SSL_SOCKET_CLASS eq "Net::SSL") {
> # The underlying SSLeay classes fails to work if the socket is
> # placed in non-blocking mode. This override of the blocking
> # method makes sure it stays the way it was created.
> *blocking = sub { };
> }
Original question
Relevance: It is annoying to see your HTTPS client block indefinitely because the connection endpoint is unreliable.
This experiment is easy to set up and replay at home. You just need two things, a tarpit to trap an incoming client, and a Perl script. The tarpit can be set up using netcat:
nc -k -l localhost 9999 # on Linux, for multiple requests
nc -l -p 9999 localhost # on Cygwin, for one request only
Then, point the script to this tarpit:
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
print 'LWP::UserAgent::VERSION ', $LWP::UserAgent::VERSION, "\n";
print 'IO::Socket::SSL::VERSION ', $IO::Socket::SSL::VERSION, "\n";
my $ua = LWP::UserAgent->new( timeout => 5, keep_alive => 1 );
$ua->ssl_opts( timeout => 5, Timeout => 5 ); # Yes - see note below!
my $rsp = $ua->request( GET 'https://localhost:9999' );
if ( $rsp->is_success ) {
print $rsp->as_string;
} else {
die $rsp->status_line;
}
What is this going to do? Well, connect to the port opened by NetCat, and then ... hang. Indefinitely. At least in terms of developer time. I mean it might time out after ten minutes or two hours, but I haven't checked; the specified timeout doesn't take effect, not on Linux, and not on Windows (Win32, haven't checked Cygwin).
Versions used:
LWP::UserAgent::VERSION 6.02
IO::Socket::SSL::VERSION 1.44
# on Linux
LWP::UserAgent::VERSION 6.02
IO::Socket::SSL::VERSION 1.44
# on Win32
Now for the timeout and Timeout parameters. The former is the name of the parameter for LWP::UA, the latter is the name for IO::Socket::SSL, used via LWP::Protocol::https. (Incidentally, why is metacpan HTTPS? Well, at least it's not a tarpit.) I am somehow hoping to have these parameters passed along :)
Just so you know, keep_alive doesn't have anything to do with the timeout not working, I verified that empirically. :)
Anyway, before digging deeper, does anyone know what's going on here and how to make the timeout work with HTTPS? Hard to believe I'm the first person running into this.
This is a result of the Net::HTTPS module overriding the blocking method of IO::Socket with a noop. Upgrading to the latest Net::HTTP package should fix this.
The timeout (and Timeout) options apply only to the connection -- how many seconds will LWP::UserAgent wait while connecting -- they are not for setting a timeout on the whole transaction.
You'll want to use Perl's alarm with a $SIG{ALRM} handler to timeout the whole transaction. See perldoc -f alarm or perlipc.
local $SIG{ALRM} = sub { die "SSL timeout\n" };
my $ua = LWP::UserAgent->new( timeout => 5, keep_alive => 1 );
$ua->ssl_opts( timeout => 5, Timeout => 5 );
eval {
alarm(10);
my $rsp = $ua->request( GET 'https://localhost:9999' );
if ( $rsp->is_success ) {
print $rsp->as_string;
} else {
die $rsp->status_line;
}
};
alarm(0);
if ($#) {
if ($# =~ /SSL timeout/) {
warn "request timed out";
} else {
die "error in request: $#";
}
}
(tested on Linux. Alarms can be a bit more cantankerous in Windows/Cygwin)
I asked this question on PerlMonks, and received an answer to the effect that:
The underlying IO::Socket::INET does not support non-blocking sockets
on Win32, thus non-blocking IO::Socket::SSL is not supported on Win32,
which means also, that timeouts don't work (because they are based on
non-blocking). See also http://www.perlmonks.org/?node_id=378675
http://cpansearch.perl.org/src/SULLR/IO-Socket-SSL-1.60/README.Win32
The PerlMonks post pointed to is from 2004. Not sure the information still applies; after all, I've seen the timeout does work on Windows, just not via SSL.
I have the following (working) perl script:
use Net::SNMP;
# create session to the host
my ($session, $error) = Net::SNMP->session(
-hostname => $hostname,
-version => 'snmpv3',
-username => 'my_user_name',
-authkey => 'my_authkey',#actually, here stands the real authkey as configured on the switch
-privkey => 'my_privkey',#same as on switch
-authprotocol => 'sha',
-privProtocol => 'des'
);
if (!defined($session)) {
print $error . "\n";
last;
}
# retrieve a table from the remote agent
my $result = $session->get_table(
-baseoid => $MAC_OID
);
if (!defined($result)) {
print $session->error . "\n";
$session->close;
last;
}
#print out the result of the snmp query
#....
Now I wanted to use snmpwalk or snmpget with the same keys. For that, I created a snmp.conf file in .snmp of my home directory with the following content:
defSecurityName my_user_name
defContext ""
defAuthType SHA
defSecurityLevel authPriv
defAuthPassphrase my_auth_key here
defVersion 3
defPrivPassphrase my_privkey here
defPrivType DES
As I see it, I use the same credentials in the script and for snmpget. Why do I get snmpget: Authentication failure (incorrect password, community or key) ?
That depends on the version of snmpget and snmpset you use. When I tested an older version of net-snmp against my C# based SNMP agent http://sharpsnmplib.codeplex.com I noticed that for SHA authen mode + DES privacy mode a bug prevented the net-snmp command line tools from generating the correct message bytes (the encryption is wrong so that no agent can decrypt it).
My suggestion is that you try to use Net::SNMP instead, as like you found out, it is not affected by the same bug.
Your problem is that you're using an authentication key for Net::SNMP and a password for the command-line net-snmp tools. Based on your Net::SNMP usage you're actually using 'localized' keys. Which means the right tokens for your snmp.conf file are:
defAuthLocalizedKey 0xHEXSTRING
defPrivLocalizedKey 0xHEXSTRING
See the snmp.conf manual page for further details.
While connecting to the remote host using the Net::SSH::Expect module, 2 out of 10 times I get the error SSHConnectionAborted.
I an unable to find the reason for this error and its solution. Can anybody please help me in this?
I am using the following Perl code:
my $Ssh = Net::SSH::Expect->new(
host => 15.178.209.112,
user => Administrator,
password => Password,
raw_pty => 1,
timeout => 10,
log_stdout => 1
);
eval {$Ssh_Login = $Ssh->login();};
Do not use Net::SSH::Expect, it is just not reliable!
Net::SSH2, Net::OpenSSH (does not work on Cygwin or Windows) or even Net::SSH::Perl are better options.
Update: If all of those fail, Expect may still be a good option.