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

So I'm trying to connect to our SFTP server via a Perl script using Net::OpenSSH and Net::SFTP::Foreign, but I've never worked with with these modules before, and I'm having trouble getting the script to actually put a file on my ftp server. My script is below.

#!/usr/bin/perl use lib "PATH TO Net::OpenSSH libraries"; use Net::OpenSSH; use IO::Pty; use Net::SFTP::Foreign; use Time::Piece; $host = "SFTP ADDRESS"; $user = "SFTP USERNAME"; $pw = "SFTP PASSWORD"; $putFile = "/usr/local/nagios/Misc/sftptest"; $getFile = "sftptest"; $date = localtime->strftime('%m/%d/%Y %H:%M'); open SFILE, ">$putFile" or die $!; print SFILE "$date\n"; close (SFILE); $ssh = Net::OpenSSH->new(host=>$host, user=>$user, password=>$pw) or d +ie "can't :(\n" . $ssh->error; $sftp = $ssh->sftp(); $sftp->put($putFile) or die "Can't put\n" . $sftp->error; $sftp->get($getFile, "/usr/local/nagios/Misc/test/sftptest") or die "C +an't get\n" . $sftp->error; open SFILE, "/usr/local/nagios/Misc/test/sftptest" or die $!; while(<SFILE>){ chomp; $fileOut = $_; } print $fileOut; exit;

So what I don't understand is what do I pass into the sftp() method that ssh is calling? In the Net::OpenSSH documentation, it says %sftp_opts, but since I'm connecting using the SSH connection string, what goes there? Currently if I leave it blank I get the error "Can't call method "put" on an undefined value at /usr/local/nagios/Working/sftp_fresh.pl" Thanks for the help!

Replies are listed 'Best First'.
Re: How to connect to SFTP via OpenSSH
by tangent (Parson) on Aug 26, 2014 at 00:10 UTC
    I tried your script and it worked fine for me, i.e. it created the sftp object and I was able to retrieve a file. Try adding:
    my $sftp = $ssh->sftp() or die "Can't create sftp: " . $ssh->error;

      ALright, so when I add the error string to the end of my sftp() method, it returns:

      Permission denied (publickey, password). unable to establish master SSH connection: bad password or master proc +ess exited unexpectedly at line 23

      I've tested the password in one of my SFTP clients just to be sure everything was right and it worked fine.

        Your problem is that you are not making the SSH connection in the first place. Where you have:
        $ssh = Net::OpenSSH->new(host=>$host, user=>$user, password=>$pw) or d +ie "can't :(\n" . $ssh->error;
        that is not actually testing for failure as new() always succeeds - from the Net::OpenSSH docs:
        This method always succeeds in returning a new object. Error checking +has to be performed explicitly afterwards: my $ssh = Net::OpenSSH->new($host, %opts); $ssh->error and die "Can't ssh to $host: " . $ssh->error;
        I suspect one of your parameters is incorrect. When I log in via SSH I use: ssh username@username.example.com. That translates to:
        my $host = "username.example.com"; my $user = "username"; my $pw = "password";
        Also, if you use public key authentication (which you really should) then you need to provide the path to your key.
Re: How to connect to SFTP via OpenSSH
by salva (Canon) on Aug 26, 2014 at 07:02 UTC
    So what I don't understand is what do I pass into the sftp() method that ssh is calling?

    Net::SFTP::Foreign constructor supports several optional parameters besides those that define how to connect to the remote host (i.e. autodie, autoflush, etc.). These are the arguments you can pass into Net::OpenSSH sftp method. Passing nothing as you are doing in your script is also right.

    The problem with your script is that it fails to establish the SSH connection. Follow tangent advice above and correct the way you check for errors.