SSH with Perl using file descriptors, not Net :: SSH

Before asking a question:

I can’t use the cpan Net :: SSH module, I want, but I can’t, no amount of beggars will change this fact.

I need to open an SSH connection, open it and read stdout from it and write it to stdin. So far, my approach has been to open it in a pipe, but I could not get past this, it immediately dies.

What I mean, I understand that this leads to a fork. I wrote the code for this fork (or so I think).

Below is the skeleton of what I want, I just need a system to work.

#!/usr/bin/perl use warnings; $| = 1; $pid = open (SSH,"| ssh user\@host"); if(defined($pid)){ if(!$pid){ #child while(<>){ print; } }else{ select SSH; $| = 1; select STDIN; #parent while(<>){ print SSH $_; while(<SSH>){ print; } } close(SSH); } } 

I know how I look, I'm trying to recreate "system ('ssh user @host"), "this is not my ultimate goal, but knowing how to do this brings me closer to the ultimate goal.

Basically, I need a file descriptor for an open ssh connection, where I can read the output from it and write the input to it (not necessarily directly from my STDIN program, anything, variables, yada yada)

This includes entering a password.

I know about key pairs, part of the ultimate goal involves creating key pairs, but the connection must occur regardless of their existence, and if they do not exist, it is part of my plan to make them exist.

+4
source share
4 answers

This works for me:

 use strict; use warnings; my $pid = open my $SSH, '-|', 'ssh user@example.com ' // die $!; if ($pid) { while( <$SSH> ) { print $_; } } else { while( <> ) { print $SSH $_; } } close $SSH or die $!; 
+2
source

Consider using autossh and configuring port forwarding from the local port using the ssh -L switch, and then only connecting to the local port. This greatly simplifies the programming task due to minimal setup.

Automatically creating key pairs is a really bad idea; they must be installed in advance. Somehow automating is just asking for security issues.

If you really need to deal with ssh and password requests, Expect is an old-school way. I'm not sure what cool kids are using right now. Update: I forgot, but there is a clean perl module Net :: SSH :: Expect that runs the ssh program for you; you probably want to use it or borrow heavily from it.

+1
source

If you can, use Net :: OpenSSH or Net :: SSH2 . For instance:

 use Net::OpenSSH; my $ssh = Net::OpenSSH->new($host, user => $user, password => $password); my ($in, $out, $pid) = $ssh->open2($remote_cmd); 

Otherwise, use IPC :: Open2 to open bidirectional communication:

 use IPC::Open2 qw(open2); my $pid = open2(my $in, my $out, $ssh_cmd); 

Or for a more complex and complex implementation that also supports password authentication (via Expect ), see the source code for Net :: SFTP :: Foreign :: Backend :: Unix :: _ open4

0
source

This is too complicated for details here, but using an ssh master connection (via ControlMaster) is an alternative to using OpenSSH. After installation, all subsequent SSH connections, regardless of the method (including the open $ SSH '| -' 'ssh user @host "command"), are multiplexed through master without the need for re-authorization and without the overhead of creating new SSH every time. To some extent, this works with OpenSSH.

Unfortunately, the method that I propose is not available in the native Microsoft Windows environment.

0
source

Source: https://habr.com/ru/post/1333532/


All Articles