Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Net::SSH::Perl pty problem with SSH2? SOLVED

by cmv (Chaplain)
on Dec 22, 2008 at 21:20 UTC ( #732192=perlquestion: print w/replies, xml ) Need Help??

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


Given machine A, B, and C...

I'm trying to login from A to B and remotely execute an interactive command on C.

A is running a perl script that uses Net::SSH:Perl to machine B. This works fine for both SSH1 and SSH2.

Then A tries to run ssh -t -l $usr2 $machineC icommand" from machine B

This will work for SSH1, but will fail for SSH2 failing with:
ERR: Pseudo-terminal will not be allocated because stdin is not a terminal.

Machine A has been both a Sun and MacOS, and I see the same failure. My research indicates that Net::SSH::Perl is failing to setup the tty on machine B. Although I'm running an older version of Net::SSH::Perl, I don't see any code in the new version to fix this either.

Test code is attached - using "uname-a" instead of an interactive command, and ssh -t to force the error.

Any thoughts on how I can get this to work with SSH2?



UPDATE: I was able to modify to fix this problem. A bug report has been submitted along with my code hacks to that make it work.

use strict; use warnings; use Net::SSH::Perl; use Net::SSH::Perl::Constants qw( :msg ); my $host1='machineB'; my $usr1='usrB'; my $pass1='passwdB'; my $host2 = 'machineC'; my $usr2 = 'usrC'; my $cmd = "/opt/exp/bin/ssh -t -l $usr2 $host2 uname -a"; my $debug=0; my $ssh1 = Net::SSH::Perl->new($host1, use_pty=>1, protocol=>1, interactive=>1, debug=>$debug) || die "Cannot conntact target machine, exiting..."; $ssh1->login($usr1, $pass1) || die "Bad login, exiting..."; print STDERR "\n\nUsing SSH1 Protocol\n"; my ($out, $err, $exit) = $ssh1->cmd($cmd); print STDERR "exit=$exit\n"; print STDERR "OUT: $out\n" if $out; print STDERR "ERR: $err\n" if $err; # Using SSH2... # Adding use_pty=>1 does not work when using SSH2. See: # +tml my $ssh2 = Net::SSH::Perl->new($host1, protocol=>2, use_pty=>1, interactive=>1, debug=>$debug) || die "Cannot conntact target machine, exiting..."; $ssh2->login($usr1, $pass1, 0) || die "Bad login, exiting..."; print STDERR "\n\nUsing SSH2 Protocol\n"; ($out, $err, $exit) = $ssh2->cmd($cmd); print STDERR "exit=$exit\n"; print STDERR "OUT: $out\n" if $out; print STDERR "ERR: $err\n" if $err;

Replies are listed 'Best First'.
Re: Net::SSH::Perl pty problem with SSH2?
by zentara (Archbishop) on Dec 22, 2008 at 21:32 UTC
      zentara++ Thanks for the pointer. Alas, I have restrictions that I don't believe will let me use anything in the referenced thread.

      Although I'm developing on MacOS and Sun, this perl script (for machine A) will need to run on Windows PCs too. I've already built an infrastructure around Net::SSH::Perl, for other things this tool needs to do on all platforms, and it would be nice if I could get this new addition to work for the Windows crowd as well (Net::SSH::Perl only works with SSH2 on Windows).

      Failing that, I may have to use some form of command-line interface with putty on the windows machines.


Re: Net::SSH::Perl pty problem with SSH2?
by Crackers2 (Parson) on Dec 22, 2008 at 22:13 UTC
    Did you try adding another -t to the ssh command? The ssh manpage says "Multiple -t options force tty allocation, even if ssh has no local tty."
      Crackers2++ Good suggestion!

      When I try it, I don't get the error message, but I also don't get STDIN and STDOUT connected to the Net::SSH::Perl connection either (if I substitute the "passwd" command in there, it just exits with an error return code). I have working SSH keys setup between B and C so I know it's not an authentication problem.

      To do the interactive stuff, I need to be able to read/write from machine A to the command on machine C.



Re: Net::SSH::Perl pty problem with SSH2?
by Bloodnok (Vicar) on Dec 22, 2008 at 22:16 UTC
    SSH2 is far a more restrictive protocol than SSH1, so I'm not altogether surprised at and indeed, have seen for myself, the same, or very similar, problems.

    The only solution we came up with was to ensure that the appropriate satellite machines all had perl installed along with the latest Net::SSH and then use perl, not the shell, to communicate with the furthest machines.

    We encountered a further similar problem when attempting to use the GNU screen utility...

    A user level that continues to overstate my experience :-))
      What I'm trying to do will work from unix machines with the SSH2 protocol, using the stock ssh command:
      $ ssh -2 -t machineB "ssh -2 -t userC@machineC uname -a" usrB@machineB's password: Password: Mon Dec 22 16:34:45 CST 2008 Connection to machineC closed. Connection to machineB closed.
      Taking the -t off of machineB's ssh will cause the error to occur.

      I would think that we should be able to make Net::SSH::Perl do the same thing, shouldn't we?


        What I'm trying to do will work from unix machines with the SSH2 protocol

        You'll possibly find that you get better mileage (on both Windows and Linux) with Net::SSH2 than you do with Net::SSH::Perl/Net::SSH::W32Perl. Of course, you're then limited to the SSH2 protocol.

        I can't see why not - but that, like most of perl (& indeed CPAN), is down to 'us' to change if we see fit. Let us know how your work progresses cmv - I look forward to seeing the Net:SSH update :-D

        A user level that continues to overstate my experience :-))
Re: Net::SSH::Perl pty problem with SSH2?
by eye (Chaplain) on Dec 23, 2008 at 07:51 UTC
    Here's a different approach, albeit less efficient, that only uses things that seem to be working for you. I'm not in a place where I can test code, so I'm just going to sketch this out in terms of ssh commands. You are trying to connect from A to B and then from B to C:
    ssh -t -l usrB machineB ssh -t -l usrC machineC uname -a
    Instead, try connecting from A to B and creating a tunnel from B:2222 to C:22. Then connect from A to B:2222:
    ssh -f -N -l usrB machineB -L 2222:machineC:22 ssh -t -p 2222 -l usrC machineB uname -a
    A key difference here is that the main process has to start the first ssh process and then resume execution while the ssh process continues. I've never tried this from a script, so it is possible that it requires a fork. If this does work, you can reduce the added overhead by choosing weaker encryption for the tunnel's data and rely on your second connection for security.
      eye++ Thanks for the suggestion.

      This works really well when you are allowed to do it. My problem is that machine B is pretty well locked down (you can read more gory details in Populating authorized_keys with Expect) and I can't do port forwarding there.

      I'm still fiddling with various methods to solve my dilemma, and am getting close with Net::SSH::Perl. I think I'm going to dive into the code today and see if I can get SSH2 pty's working.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://732192]
Approved by ww
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (5)
As of 2020-05-27 12:25 GMT
Find Nodes?
    Voting Booth?
    If programming languages were movie genres, Perl would be:

    Results (155 votes). Check out past polls.