anthski has asked for the wisdom of the Perl Monks concerning the following question:

Hey guys,

I've got a simple engine which forks and attempts to make simaltaneous ssh connections to various (and different) hosts.

To do this, I'm using Parallel::ForkManager and the Net::SSH::Perl module.

My problem is that if I attempt to make these ssh connections in parallel/simaltaneously, then they are always unsuccessful.

With debug mode on, Net::SSH::Perl outputs

Verifying server signature. Waiting for NEWKEYS message. Enabling incoming encryption/MAC/compression. Send NEWKEYS, enable outgoing encryption/MAC/compression. Sending request for user-authentication service.

before croaking with the message:

Connection closed by remote host. at /usr/lib/perl5/site_perl/5.8.0/Ne +t/SSH/Perl/AuthMgr.pm line 43

Yet if I make my engine make these connections in a 'one at a time' fashion by setting Parallel:ForkManagers max probes setting to 1, then they always connect in succession without a problem.

My code for an ssh connection is very simple.

#!/usr/bin/perl -w use strict; use Net::SSH::Perl; my $sshusername = "anthski"; my $sshpasswd = "somepassword"; my $host = "192.168.0.1"; my $command = "date"; my $ssh = Net::SSH::Perl->new($host, debug => 1, protocol => 2); my $loginStatus = $ssh->login($sshusername,$sshpasswd); my $stdout; my $stderr; my $exit; eval { ($stdout,$stderr,$exit) = $ssh->cmd($command); }; if ($@) { if ($@ =~ m/Permission denied/i) { print "Authentication failed\n"; exit 1; } } print "$stdout\n";

The remote servers are a mix of solaris and redhat boxes (7.3 and AS4). All the connections work by hand as well as when run individually.

Has anyone ran into a similar problem? Anyone with any gotchas to share about Net::SSH::Perl and simaltaneous connections, or any advice (which may be non-Perl orientated) about why these connections may fail? Perhaps there's some ssh_config option that I need to pass...

cheers,
Anth

Replies are listed 'Best First'.
Re: Net::SSH::Perl and simaltaneous connections
by eXile (Priest) on Aug 25, 2005 at 04:52 UTC
    No idea on what the exact problem is here, but i can give you a suggestion on how i'd go about trying to solve it:

    Try replacing Net::SSH::Perl, with Expect, where in Expect you can use your local ssh-client. In the tutorials section there's a good intro into using Expect.

    If that solves your problem, it's likely a problem in Net::SSH::Perl.

      Sorry for the few days delay in response, but in case someone else comes across this thread and a similar problem, I rewrote my script to simply do a `ssh ...` instead of Net::SSH::Perl and this worked fine when running under Parallel::ForkManager. I can now perform multiple simaltaneous ssh requests against a given host.

      It's also far quicker (a matter of a second to execute versus 30+ seconds for Net::SSH::Perl).

      Perhaps not as smooth as using the complete perl solution, but it works.

      cheers,
      Anth

Re: Net::SSH::Perl and simaltaneous connections
by sk (Curate) on Aug 25, 2005 at 03:33 UTC
    I am not quite sure why it would work with one session at a time but fail for multiple ones.

    Is it possible that your server detects too many sessions from one ip and terminates the connection?

    could you please update the node with your Parallel::ForkManager code and I can run a quick check on my server?

    cheers

    SK

      Is it possible that your server detects too many sessions from one ip and terminates the connection?

      The problem is that the sessions are being made to different ip's in a concurrent fashion. So it's not just a (well not obviously at least) case of the destination server not allowing multiple simaltanoeus connections to it.

      I can quite happily make as many active and non-active connections to the same ip without drama, by both hand and through the script.

      could you please update the node with your Parallel::ForkManager code and I can run a quick check on my server?

      A cutdown, very simple version of what I'm doing would be as follows:

      #!/usr/bin/perl -w use strict; use Parallel::ForkManager; my (@hosts) = ("192.168.0.1","192.168.0.2","192.168.0.3"); my $sshscript = "ssh.pl"; my $maxProbes = 3; # set this to one to do one at a time my $pm = new Parallel::ForkManager($maxProbes); foreach my $hostname (@hosts) { $pm->start and next; my $stdout = `./$sshscript $hostname`; print "$stdout\n"; $pm->finish; } $pm->wait_all_children; print "done\n";

      with the snippet from the original node saved as ssh.pl and adjusted so that it set $host to the value of $ARGV[0]

      Cheers for your time and reply.

      Anth

        I am terribly sorry. I am going to give up on this :(

        I am on Windows XP SP2. I have to use Window$ because I don't have permissions to install modules on my Linux server.

        I just couldn't get Math::GMP to install and so protocol => 1 bombs. So i am using protocol => 2. I played around with the source code on Net::SSH::Perl but couldn't understand why my Linux servers ssh version is a no-compat!

        C:\>perl connect.pl HOME: Reading configuration data c:/.ssh/config HOME: Reading configuration data /etc/ssh_config HOME: Connecting to 192.168.2.1, port 22. HOME: Reading configuration data c:/.ssh/config HOME: Reading configuration data /etc/ssh_config HOME: Connecting to 192.168.2.8, port 22. HOME: Remote protocol version 2.0, remote software version OpenSSH_3.4 +p1 HOME: Remote protocol version 1.99, remote software version OpenSSH_3. +6.1p2 HOME: Net::SSH::Perl Version 1.28, protocol version 2.0. HOME: No compat match: OpenSSH_3.4p1. Can't set socket non-blocking: Bad file descriptor at C:/Perl/site/lib +/Net/SSH/P erl.pm line 214, <GEN0> line 1.
      I did it, but still get an error: Can't locate Net/SSH2/Perl.pm in @INC (you may need to i rl module) (@INC contains: C:/Strawberry/perl/site/lib C /lib C:/Strawberry/perl/lib .) at C:\\conn.pl line 4. BEGIN failed--compilation aborted at C:\\conn.pl line 4. Could you tel me why?