SFTP connection failure with Perl "Net::SFTP" module - perl

I am trying to connect to SFTP server using Perl but I get the following connection error: Permission denied at /app/perl-5.24.3/lib/site_perl/5.24.3/Net/SFTP.pm line 63.
My connection code 'sftp_test2.pl':
use strict;
use warnings;
use Net::SFTP;
my $server = 'downloads-server';
my $user = 'user';
my $port = "10022";
my $password = '';
my %args = (
user => "$user",
port => "$port",
ssh_args => {
user => "$user",
identity_files => [ 'path/sftp_download'],
port => "$port",
protocol=>'2,1',
debug => 1,
}
);
my $sftp=Net::SFTP->new($server, %args) or die "could not open connection to $server\n";
execution:
$>perl sftp_test2.pl
Reading configuration data path/home/.ssh/config
Reading configuration data /etc/ssh_config
Connecting to downloads-server, port 10022.
Remote version string: SSH-2.0-CrushFTPSSHD
Remote protocol version 2.0, remote software version CrushFTPSSHD
Net::SSH::Perl Version 2.14, protocol version 2.0.
No compat match: CrushFTPSSHD.
Connection established.
Sent key-exchange init (KEXINIT), waiting for response.
Using diffie-hellman-group-exchange-sha256 for key exchange
Host key algorithm: ssh-rsa
Algorithms, c->s: aes256-ctr hmac-sha2-512-etm#openssh.com none
Algorithms, s->c: aes256-ctr hmac-sha2-512-etm#openssh.com none
Entering Diffie-Hellman Group Exchange.
SSH2_MSG_KEX_DH_GEX_REQUEST(2048<4096<8192) sent
Sent DH Group Exchange request, waiting for reply.
Received 4096 bit DH Group Exchange reply.
Generating new Diffie-Hellman keys.
Entering Diffie-Hellman key exchange.
Sent DH public key, waiting for reply.
Received host key, type 'ssh-rsa'.
Host 'downloads-server' is known and matches the host key.
Verifying server signature.
Send NEWKEYS.
Waiting for NEWKEYS message.
Enabling encryption/MAC/compression.
Sending request for user-authentication service.
Service accepted: ssh-userauth.
Trying empty user-authentication request.
Authentication methods that can continue: password,publickey,keyboard-interactive.
Next method to try is password.
Trying password authentication.
Will not query passphrase in batch mode.
Authentication methods that can continue: password,publickey,keyboard-interactive.
Next method to try is password.
Trying password authentication.
Will not query passphrase in batch mode.
Authentication methods that can continue: password,publickey,keyboard-interactive.
Next method to try is password.
Trying password authentication.
Will not query passphrase in batch mode.
Authentication methods that can continue: password,publickey,keyboard-interactive.
Next method to try is password.
Next method to try is publickey.
Publickey: testing agent key 'my-server'
Authentication methods that can continue: password,publickey,keyboard-interactive.
Next method to try is password.
Next method to try is publickey.
Publickey: testing agent key 'path/home/.ssh/id_rsa'
Authentication methods that can continue: password,publickey,keyboard-interactive.
Next method to try is password.
Next method to try is publickey.
Trying pubkey authentication with key file 'path/sftp_download'
Authentication methods that can continue: password,publickey,keyboard-interactive.
Next method to try is password.
Next method to try is publickey.
Permission denied at /app/perl-5.24.3/lib/site_perl/5.24.3/Net/SFTP.pm line 63.
I thought that it is related to my private key, but I can connect via unix command:
sftp -oPort=10022 -oIdentityFile=path/sftp_download user#downloads-server
Connecting to downloads-server...
sftp>
I tried to find a solution in many articles and also tried few code variations, but without a success.
Am I doing something wrong?
Is it a known bug? any workaround?
How can I debug it to find the reason (I am not very well familiar with SSH/FTP).
EDIT:
I suspected that it may be related to multiple connection failing attempts with password so I removed the password authentication from "%AUTH_MAP" in the file "app/perl-5.24.3/lib/site_perl/5.24.3/x86_64-linux/Net/SSH/Perl/AuthMgr.pm" and it connected as expected!
Is there a way to force using only/first key authentication?
Thanks in advance!
Mike

The code to disable password authentication (only authentication key) is:
ssh_args => {
user => $user,
options => [ 'PasswordAuthentication no' ],
identity_files => [ 'path/sftp_download'],
port => $port,
protocol =>'2,1',
debug => 1,
}

Related

Trust self-signed certificate for Email::Sender::Transport::SMTPS in perl

Trying to use Email::Sender::Transport::SMTPS for sending email. My transport is:
my $transport = Email::Sender::Transport::SMTPS->new({
host => $smtpserver,
ssl => 'starttls',
sasl_username => $smtpuser,
sasl_password => $smtppassword,
debug => 1,
});
When trying send the email, the debug says:
Net::SMTPS=GLOB(0x7f893b2b00f0)<<< 250-SIZE 52428800
Net::SMTPS=GLOB(0x7f893b2b00f0)<<< 250-8BITMIME
Net::SMTPS=GLOB(0x7f893b2b00f0)<<< 250-PIPELINING
Net::SMTPS=GLOB(0x7f893b2b00f0)<<< 250-STARTTLS
Net::SMTPS=GLOB(0x7f893b2b00f0)<<< 250 HELP
Net::SMTPS=GLOB(0x7f893b2b00f0)>>> STARTTLS
Net::SMTPS=GLOB(0x7f893b2b00f0)<<< 220 TLS go ahead
DEBUG: .../IO/Socket/SSL.pm:735: local error: SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:738: fatal SSL error: SSL connect attempt failed error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
unable to establish SMTP connection
Probably because the server using self-signed certificate. (When using the same setting in the Thunderbird it is needed to add the "trust this certificate" setting.)
The question is: How to add the "trust this certificate" for the Email::Sender::Transport::SMTPS - thus allow sending email.
There is no direct way to give Email::Sender::Transport::SMTPS SSL specific arguments. But, since ultimately IO:Socket::SSL is used you can hack your way around this limitation. From the man page:
This is a list of typical errors seen with the use of IO::Socket::SSL:. ....
Make SSL settings inacessible by the user, together with bad builtin settings.
Some modules use IO::Socket::SSL, but don't make the SSL settings available to the user. This is often combined with bad builtin settings or defaults (like switching verification off). Thus the user needs to hack around these restrictions by using set_args_filter_hack or similar.
Thus what you could do is
IO::Socket::SSL::set_args_filter_hack( sub {
my ($is_server,$args) = #_;
$args->{SSL_fingerprint} = 'sha1$437104....'
});
With this option you could make certificate pinning trust a certificate as long as it's fingerprint matches the given one. You can get the fingerprint for instance with:
openssl s_client -connect mail.example.org:25 -starttls smtp |\
openssl x509 -fingerprint -noout
Alternative ways would be to use the certificate as trusted with the SSL_ca_file option. You could also set SSL_verify_mode to 0 (SSL_VERFY_NONE) but since this disables any kind of validation you should only use this for testing.
Please note that set_args_filter_hack is global, that is it affects all IO::Socket::SSL objects in your program. Thus depending on the program you should only set it directly before you establish the connection with Email::Sender::Transport::SMTPS and reset it immediately afterwards.
For more information about these options please read the documentation of IO::Socket::SSL.
You can control the SSL usage with the options of new() constructor method
"SSL_verify_mode"=>'SSL_VERIFY_NONE'
IN Email/Sender/Transport/SMTPS.pm
# compatible
my $ssl = $self->ssl;
$ssl = 'ssl' if $self->ssl and $self->ssl ne 'starttls';
return (
$self->host,
Port => $self->port,
Timeout => $self->timeout,
defined $ssl ? (doSSL => $ssl) : (),
defined $self->helo ? (Hello => $self->helo) : (),
defined $self->localaddr ? (LocalAddr => $self->localaddr) : (),
defined $self->localport ? (LocalPort => $self->localport) : (),
defined $self->debug ? (Debug => $self->debug) : (),
"SSL_verify_mode"=>'SSL_VERIFY_NONE',#ADDED LINE
);
EDIT: This is really bad, because as per comments you trust everything. Instead if on linux/*nix
cat tobetrusted.crt >> /etc/ssl/cert.pem

Unable to Login with Net::SSH:Perl

I am just starting to use Net::SSH::Perl and it seems that I ranning into something weird. If I set the interactive flag to 1 and input my password I am am to login remotely to the machine via ssh but if I leave the interactive flag off or set it to 0 the login fails. I confirm that I am able to use Net::SSH::Perl to log into my local machine so it must be something that I am doing wrong for this particular remote machine, which the under laying OS is SuSE. I also confirmed that I am able to ssh to the remote machine from a terminal window.
use Net::SSH::Perl;
my $cmd = 'uptime';
my $ssh = Net::SSH::Perl->new($host, interactive=> 0, debug => 1);
$ssh->login($user, $pass);
my($stdout, $stderr, $exit) = $ssh->cmd($cmd);
print $stdout;
Below is the logs that are output from debug when the interactive flag is set to 0.
localhost.localdomain: Reading configuration data /home/user/.ssh/config
localhost.localdomain: Reading configuration data /etc/ssh_config
localhost.localdomain: Connecting to 1.1.1.1, port 22.
localhost.localdomain: Remote version string: SSH-2.0-OpenSSH_5.1
localhost.localdomain: Remote protocol version 2.0, remote software version OpenSSH_5.1
localhost.localdomain: Net::SSH::Perl Version 1.38, protocol version 2.0.
localhost.localdomain: No compat match: OpenSSH_5.1
.
localhost.localdomain: Connection established.
localhost.localdomain: Sent key-exchange init (KEXINIT), wait response.
localhost.localdomain: Algorithms, c->s: 3des-cbc hmac-sha1 none
localhost.localdomain: Algorithms, s->c: 3des-cbc hmac-sha1 none
localhost.localdomain: Entering Diffie-Hellman Group 1 key exchange.
localhost.localdomain: Sent DH public key, waiting for reply.
localhost.localdomain: Received host key, type 'ssh-dss'.
localhost.localdomain: Host '1.1.1.1' is known and matches the host key.
localhost.localdomain: Computing shared secret key.
localhost.localdomain: Verifying server signature.
localhost.localdomain: Waiting for NEWKEYS message.
localhost.localdomain: Send NEWKEYS.
localhost.localdomain: Enabling encryption/MAC/compression.
localhost.localdomain: Sending request for user-authentication service.
localhost.localdomain: Service accepted: ssh-userauth.
localhost.localdomain: Trying empty user-authentication request.
localhost.localdomain: Authentication methods that can continue: publickey,keyboard-interactive.
localhost.localdomain: Next method to try is publickey.
localhost.localdomain: Publickey: testing agent key 'user#localhost.localdomain'
localhost.localdomain: Authentication methods that can continue: publickey,keyboard-interactive.
localhost.localdomain: Next method to try is publickey.
localhost.localdomain: Publickey: testing agent key 'user'
localhost.localdomain: Authentication methods that can continue: publickey,keyboard-interactive.
localhost.localdomain: Next method to try is publickey.
Permission denied at /home/user/workspace/perl-random/avamar_ssh.pl line 4.
I am guessing I am doing something wrong, so if someone could point in the right direction that would be awesome.
Thanks.
This part:
localhost.localdomain: Authentication methods that can continue: publickey,keyboard-interactive.
means that the server is allowing two methods for authenticating:
publickey — public-key authentication
You mention in a comment that this not an option for you.
keyboard-interactive — where you enter a password
It should hardly come as a surprise that this only works in interactive mode.
So, what you're trying to do is not possible.
The good news is, this sounds like the X-Y Problem. If you give us more details about your real problem, we may be able to suggest a better approach.

Using Net::SSH::Perl with public key

I want to gain access to an AWS Instance using Perl. I can access the instance from commandline like this:
ssh -i my-key-pair.pem ubuntu#ec2-**-***-***-***.us-west-2.compute.amazonaws.com
but my code doesn't work:
#! usr/bin/perl
use Net::SSH::Perl;
$user = "ubuntu";
$host = "ec2-**-***-***-***.us-west-2.compute.amazonaws.com";
#KEYFILE = "my-key-pair.pem";
$ssh = Net::SSH::Perl->new($host, debug=>1, identity_files=>\#KEYFILE);
$ssh->login($user);
As I mentioned I'm new to this concept, it might be a simple solution, I couldn't find a solution online, hopefully you can help me.
the output is this:
atakanarikan#atakanarikanhplaptop:~/Desktop$ perl remotecomp
atakanarikanhplaptop: Reading configuration data /home/atakanarikan/.ssh/config
atakanarikanhplaptop: Reading configuration data /etc/ssh_config
atakanarikanhplaptop: Connecting to ec2-**-***-***-***.us-west-2.compute.amazonaws.com, port 22.
atakanarikanhplaptop: Remote version string: SSH-2.0-OpenSSH_6.6p1 Ubuntu-2ubuntu1
atakanarikanhplaptop: Remote protocol version 2.0, remote software version OpenSSH_6.6p1 Ubuntu-2ubuntu1
atakanarikanhplaptop: Net::SSH::Perl Version 1.37, protocol version 2.0.
.takanarikanhplaptop: No compat match: OpenSSH_6.6p1 Ubuntu-2ubuntu1
atakanarikanhplaptop: Connection established.
atakanarikanhplaptop: Sent key-exchange init (KEXINIT), wait response.
atakanarikanhplaptop: Algorithms, c->s: 3des-cbc hmac-sha1 none
atakanarikanhplaptop: Algorithms, s->c: 3des-cbc hmac-sha1 none
atakanarikanhplaptop: Entering Diffie-Hellman Group 1 key exchange.
atakanarikanhplaptop: Sent DH public key, waiting for reply.
atakanarikanhplaptop: Received host key, type 'ssh-dss'.
atakanarikanhplaptop: Host 'ec2-**-***-***-***.us-west-2.compute.amazonaws.com' is known and matches the host key.
atakanarikanhplaptop: Computing shared secret key.
atakanarikanhplaptop: Verifying server signature.
atakanarikanhplaptop: Waiting for NEWKEYS message.
atakanarikanhplaptop: Send NEWKEYS.
atakanarikanhplaptop: Enabling encryption/MAC/compression.
atakanarikanhplaptop: Sending request for user-authentication service.
atakanarikanhplaptop: Service accepted: ssh-userauth.
atakanarikanhplaptop: Trying empty user-authentication request.
atakanarikanhplaptop: Authentication methods that can continue: publickey.
atakanarikanhplaptop: Next method to try is publickey.
atakanarikanhplaptop: Trying pubkey authentication with key file 'my-key-pair.pem'
atakanarikanhplaptop: Will not query passphrase for 'my-key-pair.pem' in batch mode.
atakanarikanhplaptop: Loading private key failed.
Permission denied at remotecomp line 8.
These two lines
atakanarikanhplaptop: Will not query passphrase for 'my-key-pair.pem' in batch mode.
atakanarikanhplaptop: Loading private key failed.
seem to point to the issue. Your private key is protected by a passphrase, and when you try to use it, it wants to ask you for it, but can't in batch mode.
I think you're going to have to remove the passphrase from your private key to use this module. There are many tools, including OpenSSL, that can do that for you. Just search the documentation for removing a passphrase from a key.

Net::SFTP Hangs

I'm using Net::SFTP to transfer files. However, whenever I try to create a new object like so:
my $sftp = Net::SFTP->new('ip', user=>'user', password=>'pass');
It just hangs and does nothing. Does anyone know why this is? Am I doing something wrong? Thanks!
Update
Here is the debug output:
dev1.com: Reading configuration data /home/user/.ssh/config
dev1.com: Reading configuration data /etc/ssh_config
dev1.com: Connecting to 50.56.91.91, port 22.
dev1.com: Remote protocol version 2.0, remote software version OpenSSH_4.3
dev1.com: Net::SSH::Perl Version 1.34, protocol version 2.0.
dev1.com: No compat match: OpenSSH_4.3.
dev1.com: Connection established.
dev1.com: Sent key-exchange init (KEXINIT), wait response.
dev1.com: Algorithms, c->s: 3des-cbc hmac-sha1 none
dev1.com: Algorithms, s->c: 3des-cbc hmac-sha1 none
dev1.com: Entering Diffie-Hellman Group 1 key exchange.
dev1.com: Sent DH public key, waiting for reply.
dev1.com: Received host key, type 'ssh-dss'.
dev1.com: Host 'ip_here' is known and matches the host key.
dev1.com: Computing shared secret key.
dev1.com: Verifying server signature.
dev1.com: Waiting for NEWKEYS message.
dev1.com: Send NEWKEYS.
dev1.com: Enabling encryption/MAC/compression.
dev1.com: Sending request for user-authentication service.
dev1.com: Service accepted: ssh-userauth.
dev1.com: Trying empty user-authentication request.
dev1.com: Authentication methods that can continue: publickey,gssapi-with mic,password.
dev1.com: Next method to try is publickey.
dev1.com: Trying pubkey authentication with key file '/home/user/.ssh/id_rsa2'
In addition to the user and password options, set debug => 1. You will get some diagnostic output that may tell you what the problem is.
Search if your connection data is correct. Use a simple code like that showed in Net::SFTP::Foreign .

Why is ssh prompting me for a password after I give it to Perl's Net::SSH::Perl?

I am using Net::SSH::Perl to execute a command on a remote server as follows:
use Net::SSH::Perl;
my $ssh = Net::SSH::Perl->new($host);
$ssh->login($user, $pass);
my ($stdout, $stderr, $exit) = $ssh->cmd($cmd);
But when I execute the above script, a password prompt comes again. Meaning the password I supplied in $pass is not taken to establish the ssh connection. Why is this? Any idea how I can overcome this? I give below the debug info:
serv1: Reading configuration data /root/.ssh/config
serv1: Reading configuration data /etc/ssh_config
serv1: Allocated local port 1023.
serv1: Connecting to 15.154.59.63, port 22.
serv1: Remote protocol version 1.99, remote software version OpenSSH_4.2
serv1: Net::SSH::Perl Version 1.34, protocol version 1.5.
serv1: No compat match: OpenSSH_4.2.
serv1: Connection established.
serv1: Waiting for server public key.
serv1: Received server public key (768 bits) and host key (1024 bits).
serv1: Host '15.154.59.63' is known and matches the host key.
serv1: Encryption type: DES3
serv1: Sent encrypted session key.
serv1: Received encryption confirmation.
serv1: RSA authentication failed: Can't load public key.
serv1: Doing challenge response authentication.
Password:
The password prompt should not be coming right, given that I have already supplied the password in $pass variable?
UPDATE(Based on the comments received):
I tried the following:
my $ssh = Net::SSH::Perl->new($host, debug =>1, identity_files => []);
Now, I don't get the message "RSA authentication failed: " but still the password prompt appears. I give below the debug info:
serv1: Allocated local port 1023.
serv1: Connecting to 15.154.59.63, port 22.
serv1: Remote protocol version 1.99, remote software version OpenSSH_4.2
serv1: Net::SSH::Perl Version 1.34, protocol version 1.5.
serv1: No compat match: OpenSSH_4.2. kf-linux-dm3: Connection established.
serv1: Waiting for server public key.
serv1: Received server public key (768 bits) and host key (1024 bits).
serv1: Host '15.154.59.63' is known and matches the host key.
serv1: Encryption type: DES3
serv1: Sent encrypted session key.
serv1: Received encryption confirmation.
serv1: Doing challenge response authentication.
Password:
Could someone enlighten me?
This line in your errors:
serv1: RSA authentication failed: Can't load public key.
tells me that your program is trying to do automatic logins, which is not what you want to do when you need a password to log in.
Check the Perl/ssh documentation:
identity_files
A list of RSA/DSA identity files to be used in RSA/DSA authentication. The value of this argument should be a reference to an array of strings, each string identifying the location of an identity file. Each identity file will be tested against the server until the client finds one that authenticates successfully.
If you don't provide this, RSA authentication defaults to using $ENV{HOME}/.ssh/identity, and DSA authentication defaults to $ENV{HOME}/.ssh/id_dsa.
You might try setting identity_files to an empty array, to see if that forces it to use your supplied password; or you could go ahead and set up public key authentication like in the link above.
serv1: Doing challenge response authentication.
That's your key line. SSH actually has multiple types of password-like authentication. One of them is strait password authentication (controlled by the PasswordAuthentication option in /etc/sshd_config), I suspect that is what the $pass you sent is for. Another one is challenge-response authentication, where the server sends one or more challenges, and you are expected to reply with the correct responses. Ref and Spec.
So, technically, ssh isn't asking you for a password. Its asking you for a reply to an arbitrary challenge from the server, and that challenge just happens to be "Password:".
Possibly, it'll work if you use Net::SSH::Perl::KeyboardInt explicitly?
Of course, you really ought to set up RSA public key authentication.
You need to disable ChallengeResponse authentication:
#!/usr/bin/perl
use strict;
use Net::SSH::Perl;
my $user = 'user';
my $pw = 'pw';
my $host = 'some.server';
my $cmd = 'id';
my %params = (
'debug' => 0,
);
# get the ssh connection object
my $ssh = Net::SSH::Perl->new($host, %params);
# get the configuration object associated with the host connection
my $cfg = $ssh->config;
# disable challenge/response authentication
my $v = $cfg->set('auth_ch_res', 0);
# set the login parameters
$ssh->login($user, $pw);
# issue the command (which is when the authentication actually takes place)
my($stdout, $stderr, $exit) = $ssh->cmd($cmd);
# do what you want with the result
print $stdout;