PERL SFTP using System, Cannot install SFTP module - perl

I'm a bit new to perl and stackoverflow. If I could use a more familiar language I would, unfortunately I cannot due to certain circumstances. Thanks in advance for the help.
Modules Not Installed: Net::SFTP, WWW::CURL, Net::SSH2, Net::SFTP::Foriegn
Modules Installed: Net::FTP
I am unable to install modules.
Unable to use Net::FTP Tried Default port and port 22, with a username and password. All I get back from the other box's log when trying to connect is "Did not receive identification string from xx.xx.xx.xx" Also unable to use FTP in command line, times out.
$ftp = Net::FTP->new($box,Port=>22, Debug => 0)
or die print "Error: Cannot connect";
$ftp->login($userBox,$passBox)
or die print "Error: Cannot login";
$ftp->cwd()
or die print "Error: Cannot change to Root";
$ftp->cwd($dir)
or die print "Error: Cannot change to selected directory";
if($copyfile ne "" && $dir ne "")
{
$ftp->put($copyfile, $copyfile);
}
$ftp->quit();
I can manually use SFTP through the linux command line, not FTP, so I have been trying to use the system command to SFTP into the other box. The other box's logs just say "Connection closed by xx.xx.xx.xx"
system('sftp '.$userBox.'#'.$box.' ENDOFINPUT'
.$passBox.'ENDOFINPUT
cd ../../../
put '.$filename.' '.$dir.'
exit
ENDOFINPUT');
If anyone knows how to help me with my problem that'd be great :)

Let's approach this from another direction... when you say you're "unable to install modules", is that just because you don't have root permission? If that's the case, you can install them locally under a user account instead.
If the machine doesn't have an internet connection to even install them locally, you can use the same technique to install them on a different box, then gzip the entire local directory where you have them installed and copy them to the target machine, and add a "use lib" statement to get at them from your script.

Are you sure that the $passBox equivalent worked on the shell?
You should be able to set-up passwordless connectivity using key-pairs, which would make THAT problem go away quite quickly.

Related

Perl - Best way to establish an SFTP connection on windows

I need to put files in a remote directory using SFTP on a Windows machine. I've tried Net::SFTP::Foreign though I can't use it because it needs IO::Pty which is not available on Windows machine. What's the best/simplest way to do this?
Update With Requested Info:
Here are the versions I'm using:
Net::SFTP::Foreign : v 1.89
Net::SSH2 : v 0.69
Net::SFTP::Foreign::Backend::Net_SSH2 : v 0.09
and here is the gist of my code:
$ssh2 = Net::SSH2->new();
$ssh2->connect($host) || die "connect failed";
$ssh2->auth_password($user, $pass) || die "password auth failed";
$sftp = Net::SFTP::Foreign->new(ssh2 => $ssh2,
backend => 'Net_SSH2');
$sftp->error and
die "Unable to stablish SFTP connection: ". $sftp->error;
Right now I'm just trying to establish a connection. I will need to put files on the server. The erro I'm receiving is as follows:
Net::SSH2::timeout(ss, timeout) at C:/Strawberry/perl/site/lib/Net/SSH2.pm line 111, <STDIN> line 1.
The preferred way to use Net::SFTP::Foreign in Windows is probably to use the Net::SFTP::Foreign::Backend::Net_SSH2 backend (update: a Perl module available from CPAN) which uses Net::SSH2 under the hood (which is already included with Strawberry Perl, update: otherwise, you will need to build and install libssh2 yourself which sometimes is not as easy as it should be).
Another option is to tell Net::SFTP::Foreign to use the plink command to run the SSH connection (search for plink on the module docs). Update:plink is part of the PuTTY application distribution, a very popular SSH client that may be already installed in that machine.
Finally you can also try using Net::SSH::Any which provides its own backend for Net::SFTP::Foreign and can run on top of several SSH clients and modules... but it is still in beta!
I have several cross-platform scripts that are using Net::SFTP::Foreign using plink on windows and openssh on linux and it works great. Windows is using the latest strawberry perl release.
my $sftp = Net::SFTP::Foreign->new(
host=> $server,
ssh_cmd => $plink, #Contains full path to plink or path to ssh
user=> $user,
more => ['-i', $keyfile],
stderr_discard => 1,
);
The only thing about using the plink backend is that you have to first manually establish a connection using psftp or Putty gui so it stores the trust confirmation in the registry. After that it is good to go from the script.
The nice thing is you can just have the actual path to ssh or to plink defined in a system level config file and the script just reads what is needed on that particular platform. ie (...\bin\Putty\plink.exe or /usr/bin/ssh )
Not a pure Perl solution, but has been very robust. I don't see IO::Pty on any of my windows boxes so no dependency there for plink.
SFTP is actually SSH with a wrapper to simulate the FTP like commands, so a mdir is actually a ssh 'ls /path/to/dir'.
While there might be a Perl SFTP package that avoids IO::Pty, you might get to your solution much faster by just translating the "FTP" commands into their ssh / scp equivalents and looking at Net::SSH
--- Adding an Example as requested ---
#!/bin/env perl
use Net::OpenSSH ();
my $connection = Net::OpenSSH->new('somehost.com', user => 'myuser', password => 'mypassword' );
my #ls = $connection->capture("ls");
printf "remote listing is %s\n", join(', ', #ls);
This should list the files to your console.
You mentioned not having IO::Pty because it is not available for a windows machine. Perhaps you should be attempting to install IO::Pty::Easy. Note that Net::OpenSSH uses IO::Pty too, but that should be possible to do on windows, provided you also install Glib as indicated in this post http://www.perlmonks.org/bare/?node_id=856863
Good luck!

[Perl][net::ssh2] How to keep the ssh connection while executing remote command

I'm working on a perl script using net::ssh2 to make a SSH connection to a remote server.
(I'm working on windows)
I chose Net::SSH2 because i had to make some SFTP connections in the same script.
For now, my sftp connections work perfectly. The problem is when i try to execute a "long-duration" command. I mean a command which execution can take more than 30sec.
$ssh2 = Net::SSH2->new();
$ssh2->connect('HOST') or die;
if($ssh2->auth(username=>'USER', password=>'PSWD'))
{
$sftp = Net::SFTP::Foreign->new(ssh2=>$ssh2, backend=>'Net_SSH2');
$sftp->put('local_path', 'remote_path');
$channel=$ssh2->channel();
##
$channel->shell('BCP_COMMAND_OR_OTHER_PERL_SCRIPT');
# OR (I tried both, both failed :( )
$channel->exec('BCP_COMMAND_OR_OTHER_PERL_SCRIPT');
##
$channel->wait_closed();
$channel->close();
print "End of command";
$sftp_disconnect();
}
$ssh2->disconnect();
When i execute this script, the connection is successfull, the file is correctly sent but the execution is not (completely) performed. I mean, I think the command is sent for execution but terminated immediatly or not sent at all, i'm not sure.
What i want is the script waits until the command is completly finished before disconnect everything (just because sometimes, i need to get the result of the command execution)
Does anyone know how to solve this? :( The cpan documentation is not very explicit for this
Thanks!
PS: I'm open to any remarks or suggestion :)
Edit: After some test, i can say that the command is sent but is interrupted. My test was to start another perl script on the remote server. This script writes in a flat file. In this test, the script is started, the file is half-filled. I mean, the file is brutaly stopped in the middle.
In the other hand, when i performed a "sleep(10)" just after the "$channel->exec()", the script goes to the end successfully.
Problem is, that I can't write a "sleep(10)" (i don't know if it will take 9 or 11 seconds (or more, you see my point)
You can try using Net::SSH::Any instead.
It provides a higher level and easier to use API and can use Net::SSH2 or Net::OpenSSH to handle the SSH connection.
For instance:
use Net::SSH::Any;
my $ssh = Net::SSH::Any->new($host, user => $user, password => $password);
$ssh->error and die $ssh->error;
my $sftp = $ssh->sftp;
$sftp->put('local_path', 'remote_path');
my $output = $ssh->capture($cmd);
print "command $cmd output:\n$output\n\n";
$sftp->put('local_path1', 'remote_path1');
# no need to explicitly disconnect, connections will be closed when
# both $sftp and $ssh go out of scope.
Note that SFTP support (via Net::SFTP::Foreign) has been added on version 0.03 that I have just uploaded to CPAN.

How to create a Zip file on a remote server in perl

actualy im using Net::FTP::Recursive to download a directory structure , it works nice for what is required. But since some folders have more than 100/ files, downloading then can take ages. Since a zip file is faster do download, how i could, using perl connect to a remote server via ftp and create a zip file from the remote server/folder to download ?
use Net::Config;
use Net::FTP::Recursive;
$ftp = Net::FTP::Recursive->new("$hostname:$ftp_port", Debug => 0)
or die "Cannot connect to $hostname: $#";
$ftp->login($iLogin,$iPass)
or die "failed ", $ftp->message;
$ftp->binary()
or die "Cannot set to Binary";
$ftp->cwd("/admin/packages/$fileName")
or die "Cannot change working directory ", $ftp->message;
$ftp->rget( $fileName );
#or die "Download Failed ", $ftp->message;
$ftp->quit;
Thank you all for your time
The site(ARGS) method is designed for that. You can send a shell command and make it runs on remote server.
http://perldoc.perl.org/Net/FTP.html#METHODS
However, most of the FTP servers I know disabled that permission, so, good luck
I think you'd need to have SSH access to the system to run a ZIP command. But if that's the case, you could also use SCP to transfer your files more securely. FTP does everything in the open.
Thanks,
F.

perl script working in vmware server but fails in vmware ESXi

This problem is really puzzling to me: I have the following script working on vmware server 2.0:
#!/usr/local/bin/perl
# server (transmitter)
use strict;
use IO::Socket::Multicast6;
use IO::Interface;
use constant GROUP => "235.1.1.2";
use constant PORT => "3000";
my $sock = IO::Socket::Multicast6->new(
Proto=>"udp",
Domain=>AF_INET,
PeerAddr=>GROUP,
PeerPort=>PORT);
$sock->mcast_if("eth1");
$sock->mcast_ttl(10);
while (1) {
my $message = localtime();
$sock->send($message) || die "Could not send: $!";
} continue {
sleep 4;
}
It works great on vmware server. I have cloned this VM to an EXSi server but running the same exact copy of the virtual machine running the script, and I get the following error:
Can't call method "mcast_if" on an undefined value
Im really puzzled by this as I am not sure what the problem could be.
there is really nothing different except for the CPU running on both machines, but I don't see how something so low level can be causing an issue but I could be wrong. perl -d wasn't very helpful.
Thanks.
It's failing to create the socket, use some error checking to try to find out why. Eg:
my $sock = IO::Socket::Multicast6->new(
Proto=>"udp",
Domain=>AF_INET,
PeerAddr=>GROUP,
PeerPort=>PORT)
or die "Socket failed: $!";
The new() constructor is failing, but not raising an exception. I don’t know its API: is there some way to get it to tell you why?
Otherwise you might try errno (that is, $!).

How can I do a CVS checkout without using the Cvs module?

How to do CVS co using Perl without using Cvs module ?
system : http://perldoc.perl.org/functions/system.html
While you asked not to use a module, I always recommend it. CPAN kicks up Cvs::Simple. You may want to consider using it as a reference if you have business case reasons for not using a module.
I wrote this up in my blog but here it is in plain text.
I had to download and install expectperl and the IO::Tty perl module. This little perl script successfully does the cvs update, even with the ssh password prompting.
#!/usr/bin/perl
use Expect;
chdir("/files/hudson_local/jobs/MOJARRA_1_2X_ROLLING_GLASSFISH_2_1_1/workspace");
$ENV{"CVSROOT"} = ":ext:8bit#java.net/cvs/javaserverfaces-sources~cvs-repository";
($cvs = Expect->spawn("cvs update -d -P")) || die "Couldn't spawn cvs, $!";
unless ($cvs->expect(30, "Enter passphrase for key '/files/hudson_local/.ssh/id_rsa':")) {
die "Never got the passphrase prompt";
}
print $cvs "not the real password\r";
unless ($cvs->expect(300, "cvs update: Updating www/legal/jsf-cddl")) {
die "Never saw update starting";
}