pysftp "paramiko.ssh_exception.AuthenticationException: Authentication failed." [duplicate] - python

This question already has answers here:
Paramiko authentication fails with "Agreed upon 'rsa-sha2-512' pubkey algorithm" (and "unsupported public key algorithm: rsa-sha2-512" in sshd log)
(5 answers)
Closed 2 months ago.
I have access to an SFTP server using username and a ppk file. All information I have are
host
username
ppk priveate key file
the password for decrypting the ppk file
There is no server password. The password is for ppk file decryption only.
If I user Filezilla, it connects to the server fine.
Now, I would like to use python to connect to the same server. It seems pysftp which is an wrapper on paramiko is only supporting pem format and not ppk keys. I used putty gen for this conversion. It seem that RSA is not acceptable so I used DSA for this conversion. Provided the ppk file and its password and generated a pem private key file.
Now, following this code:
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
srv = pysftp.Connection(host=sftp_host, username=sftp_user, private_key='auth.pem', cnopts=cnopts)
After a few seconds, I receive this error:
paramiko.ssh_exception.AuthenticationException: Authentication failed.
What would you advise?
Notes:
I have tried many stackoverflow answers and did not have any success. Therefore, please avoid linking this question to another random question with similar title. Instead please suggest a solution and wait for my feedback on why it does not work me.
I use a private key file. Please avoid referring me to the questions that use username/password for SFTP.
Please avoid referring me to the questions for SSH because I do not know how to put it in SFTP context.
This is about pysftp please do not suggest the options of paramiko. They do not work on a pysftp function.

I could eventually fix the problem. This was by lots of efforts plus the hints from user #martin-prikryl .
I share my solution code for others who will face with this problem in future.
The point is that there is a bug in the python library and you need to get around it by disabled_algorithms . I could not find such an option in pysftp so I migrated the code entirely to pure paramiko.
import paramiko
import io
with open('the_private_key.pem', 'r') as fh:
keydata = fh.read()
keyfile = io.StringIO(keydata)
mykey = paramiko.RSAKey.from_private_key(keyfile)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(sftp_host, username=sftp_user, pkey=mykey, look_for_keys=False, disabled_algorithms=dict(pubkeys=["rsa-sha2-512", "rsa-sha2-256"]))
sftp = ssh.open_sftp()
file_list = sftp.listdir()
.

Related

SSH using Python via private keys

In my script, I need to do an SSH to a remote system using a private key and dump the file into its directory.
The command I am using to SSH into the system is this:
ssh -i private_key localhost
Followed by the standard input:
Enter passphrase for key 'private_key'
I am trying to do this in a Python script, but am not sure about the way of writing a command and passing a passphrase as a parameter so that the whole sequence can be automated.
Please suggest me a way to achieve this via a library (Paramiko SSHClient) or a code snippet would be highly really appreciated.
SSHClient.connect can handle public key authentication with a simple call:
import paramiko
ssh = paramiko.SSHClient()
ssh.connect(hostname, username=username, key_filename=key_path, password=passphrase)
The password argument is used as a passphrase, when key_filename is provided.
Additionally, you will also have to verify the server's host key (as you must have done with ssh before). See Paramiko "Unknown Server".

Using ssh_config file with Paramiko

I need to connect to a server with SSH to download files. I have Ubuntu and I've set up SSH in the standard way: I have a ssh_config file in .ssh which defines a host entry (say host_key) for the server address (Hostname.com) and username, and I've set up an RSA key. So when I try to log into SSH from the command line or bash, I just need to use ssh host_key
I would like to do this in Python. The standard solutions seems to be to use Paramiko to set up the connection. I tried this:
from paramiko import SSHClient
from scp import SCPClient
ssh = SSHClient()
ssh.load_system_host_keys()
ssh.connect('host_key')
scp = SCPClient(ssh.get_transport())
# etc...
However, it always seems to hang and time out on ssh.connect('host_key'). Even when I try to include the username and password: ssh.connect('host_key', username='usrnm', password='pswd').
Are my host keys not loading properly? And would this take care of the RSA keys as well?
It only works if I use the whole Hostname.com with username and typed-out password. Which is maybe a bit insecure.
Since paramiko has a SSHConfig class, you can use it for your ~/.ssh/config.
However, it is slightly messy, I recommend you to use fabric instead of that.
Here is the code example:
from fabric.api import put
put('local path', 'remote path')
I do not think that it is common to use ssh_config file with Paramiko (or any other code/language). ssh_config is a configuration file for OpenSSH tools, not for SSH in general.
Usually, you specify your private key directly in your code as an argument of SSHClient.connect method:
How to access to a remote server using Paramiko with a public key-file
If you want to keep using ssh_config, Paramiko can parse it. Check parse_ssh_config and lookup_ssh_host_config functions. But I believe, you still have to look up the key file from the config and pass it explicitly to SSHClient.connect method.

Paramiko ssh connection without password

Currently I am logging in to the Unix server from my Windows desktop by giving a password in ssh.connect. Is there a way I can avoid giving the password?
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('ltc02.force.com',username = 'user',password = 'pwd')
stdin,stdout,stderr = ssh.exec_command("pwd")
Thanks for your support.
Yes, you can use public key authentication using a private key that has no password.
The general process is you create a new key on the client machine using
ssh-keygen -t rsa
Then you upload your public key to the server, copy paste it into :
.ssh/authorized_keys
The .ssh directory will be located in your user home directory on the server.
Of course, because your private key has no password you need to ensure you take adequate steps to protect it.
Note that this is not a Python specific answer. SSH Public Key is a standard process and the keys uses are standard RSA (or DSA) keys. So you should be able to do SSH public key authentication in any language of your choice.

Paramiko connect without asking ssh key

This is my python script to connect to server. But when I run the script, it is asking me to keying my ssh passphrase. How could I avoid to asking my ssh passphrase key?
host = '192.168.43.3'
user = 'root'
passwd = 'ppawd'
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=passwd)
transport = ssh.get_transport()
channel = transport.open_session()
channel.setblocking(1)
channel.settimeout(30)
command = "ls -a"
ssh.exec_command(command)
I ran into the same issue. I don't think the other answers here realized what the question was actually for. This is an old question but I wanted to help anyone else like me who ended up here after googling.
You need to disable the ssh agent feature allow_agent=False and then it will no longer prompt you for a passphrase. Paramiko is trying to connect to the ssh agent and I assume trying to read the key. I also added look_for_keys=False, as it will disable checking for private keys to use.
Example:
client.connect(server, port=port, username=username, password=password, look_for_keys=False, allow_agent=False)
My advice would be generating a key without a passphrase - just press enter when asked for a password while creating the key.
This key should be used specifically for your script - avoid re-using keys you use for other purposes (such as your user's interactive login), since it makes key revocation and access control harder.
A passphrase-less key has some advantages compared to hardcoding the password in your script:
The presence of a passphrase-less key makes it clear to anyone that the key is compromised as soon as anyone has access to it. Separating the password from the key hides this fact without providing any additional security.
It avoids you publishing your password to source-control accidentally (separation of source code and access control credentials)
Possibly, it'll make it less tempting to re-use any existing user's ssh key with a proper passphrase.
A few security considerations:
Remember that anyone with access to that key will get access to the remote system. You may consider putting restrictive permissions on the key file, and create a separate user for your script to login into in the remote system, if it's possible at all.
If your script is single purpose, you may also consider limiting the list of shell commands available to the user on the remote system
If you have no physical security on the system that stores the key (i.e.: a laptop or desktop in a untrusted location), you may also want to use full disk encryption, block device encryption (LUKS) or file-level encryption (encfs).
I solved the problem as
ssh-copy-id root#192.168.43.133
Credit to http://sshmenu.sourceforge.net/articles/key-setup.html
You can add the fingerprint to each server's known_hosts. For a single user:
cat ~/.ssh/known_hosts
echo "$SERVER,$PORT ssh-rsa $SERVER_KEY_FINGERPRINT" >> ~/.ssh/known_hosts
add your connection host ip to known_hosts then it will not ask for any questions like
Are you sure you want to continue connecting (yes/no)?
or if u want to disable the password asking too, then check this links
http://www.linuxproblem.org/art_9.html
https://www.debian.org/devel/passwordlessssh

How can I use sftp and mput with Python?

I'm trying to send over multiple files from one server to another using Python. I've found a few ssh2 libraries, but either I can't find documentation on them (e.g. ssh), or they don't seem to support mput.
Anyone know of any sftp libraries which support mput?
Paramiko is a library that handles SSH and related things, such as SFTP, but it only supports a regular put, no mput that I can see.
What exactly does mput do? My sftp client doesn't have that command...
Guessing from the name, I'm thinking "multiple puts" or something like that, to send multiple files in one go? If that is the case, I suggest just looping over your list of files and using put.
I was faced with a similar problem a long time ago and could not get a satisfactory mput-method to run in Python. So the paramiko library seemed to make the most sense to me.
To enable progress output or other actions in your Python application, it is advantageous to send the files individually in a for-loop. However, the overhead increases minimally with this variant.
A small Paramiko-example code :
import pysftp
import os
list_files_to_transfer = []
# Check if List is empty
if list_files_to_transfer:
# Advanced connection options beyond authentication
cnopts = pysftp.CnOpts()
# Compression for lower Transfer-Load
cnopts.compression = True
cnopts.hostkeys = None
# Establish a connection with the SFTP server
with pysftp.Connection(host=host, username=username, port=port,
private_key=os.path.abspath(path_private_key),
cnopts=cnopts) as sftp:
# Change to the specified remote directory
with sftp.cd(self.path_remote_sink_folder):
# browse the list of files
for file in list_files_to_transfer:
# Upload the file to the server
sftp.put(file)

Categories