Unable to connect to a clients SFTP using Python? [duplicate] - python

This question already has answers here:
Verify host key with pysftp
(9 answers)
Closed 2 years ago.
I have previously connected to a clients SFTP through vb.net script with WinSCP which has worked successfully however I don't want to use WinSCP.
I am newish to Python but think for my overall goal for the project will be better suited using python.
What I believe I am missing is potentially a public key and/or my privatekey is in the wrong format.
Would really appreciate some help on this as I have been stuck for days trying different things.
import pysftp
myHostname = 'sftp.name.com'
myUsername = 'username'
myPassword = 'password'
myKey = 'C:\\PrivateKey.ppk'
with pysftp.Connection(host=myHostname, username=myUsername, private_key=myKey, private_key_pass=myPassword) as sftp:
Error received
UserWarning: Failed to load HostKeys from C:\Users\name\.ssh\known_hosts.

The library is trying to find the known_hosts file to do a host key check. You can disable it, but as is written in the docs, it is strongly discouraged.
import pysftp
myHostname = 'sftp.name.com'
myUsername = 'username'
myPassword = 'password'
myKey = 'C:\\PrivateKey.ppk'
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection(host=myHostname,
username=myUsername,
private_key=myKey,
private_key_pass=myPassword,
cnopts=cnopts) as sftp:
pass
A better way would be to set the known_hosts path using the CnOpts. I don't have a Windows machine, but based on this SA answer, maybe the following will work:
import os
import pysftp
myHostname = 'sftp.name.com'
myUsername = 'username'
myPassword = 'password'
myKey = 'C:\\PrivateKey.ppk'
knownhosts_path = os.path.join(os.environ['USERPROFILE'], '.ssh', 'known_hosts')
cnopts = pysftp.CnOpts(knownhosts=knownhosts_path)
cnopts.hostkeys = None
with pysftp.Connection(host=myHostname,
username=myUsername,
private_key=myKey,
private_key_pass=myPassword,
cnopts=cnopts) as sftp:
pass

Related

sFTP with SSH Key & Password in Python [duplicate]

This question already has answers here:
Multi-factor authentication (password and key) with Paramiko
(3 answers)
Closed last year.
Trying to use pysftp to pull files from an sFTP server that requires both ssh key & password for authentication without much luck. Can use pysftp with just key and just password, but it breaks when I attempt to use both. Hoping someone has some experience with this. Open to using a different library if that works better.
Error output is:
paramiko.ssh_exception.BadAuthenticationType: Bad authentication type; allowed types: ['publickey']
import pysftp
connection_host = '1.1.1.1'
connection_user = 'username'
connection_password = 'password'
connection_private_key = '/path/to/key'
connection_dir='/dir/on/remote/host'
with pysftp.Connection(host=connection_host, username=connection_user, password=connection_password, private_key=connection_private_key) as sftp:
files = sftp.listdir(remotepath=connection_dir)
for file in files:
print("found the following file: {}".format(file))
with sftp.cd(connection_dir):
sftp.get(file)
Working code if anyone runs into the same issue:
connection_host = '0.0.0.0'
connection_user = 'username'
connection_password = 'password'
connection_private_key = '/path/to/key.pem'
connection_dir='/remote/path'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
ssh.connect(connection_host, username=connection_user, password=connection_password, key_filename=connection_private_key)
sftp_client = ssh.open_sftp()
files = sftp_client.listdir(connection_dir)
sftp_client.chdir(connection_dir)
for file in files:
print("found the following file {}".format(file))
sftp_client.get(file,file)
if sftp_client:
sftp_client.close()
if ssh:
ssh.close()

How to add ssh key correctly [duplicate]

I am writing a program using pysftp, and it wants to verify the SSH host Key against C:\Users\JohnCalvin\.ssh\known_hosts.
Using PuTTY, the terminal program is saving it to the Registry [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys].
How do I reconcile the difference between pysftp and PuTTY?
My code is:
import pysftp as sftp
def push_file_to_server():
s = sftp.Connection(host='138.99.99.129', username='root', password='*********')
local_path = "testme.txt"
remote_path = "/home/testme.txt"
s.put(local_path, remote_path)
s.close()
push_file_to_server()
The error response I am receiving is:
E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py:61:
UserWarning: Failed to load HostKeys from C:\Users\JohnCalvin\.ssh\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
warnings.warn(wmsg, UserWarning)
Traceback (most recent call last):
File "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", line 14, in <module>
push_file_to_server()
File "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", line 7, in push_file_to_server
s = sftp.Connection(host='138.99.99.129', username='root', password='********')
File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 132, in __init__
self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 71, in get_hostkey
raise SSHException("No hostkey for host %s found." % host) paramiko.ssh_exception.SSHException: No hostkey for host 138.99.99.129 found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x00000222FF3A6BE0>>
Traceback (most recent call last):
File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 1013, in __del__
self.close()
File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 784, in close
if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'
The pysftp has some bugs regarding host key handling, as described below. It also seems that the pysftp project was abandoned. Consider using Paramiko directly instead. The pysftp is just a wrapper on top of Paramiko and it does not add anything really significant. See pysftp vs. Paramiko.
For handling of host keys in Paramiko, see:
Paramiko "Unknown Server"
If you want to keep using pysftp, do not set cnopts.hostkeys = None (as the second most upvoted answer shows), unless you do not care about security. You lose a protection against Man-in-the-middle attacks by doing so.
Use CnOpts.hostkeys (returns HostKeys) to manage trusted host keys.
cnopts = pysftp.CnOpts(knownhosts='known_hosts')
with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
where the known_hosts contains a server public key(s)] in a format like:
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...
If you do not want to use an external file, you can also use
from base64 import decodebytes
# ...
keydata = b"""AAAAB3NzaC1yc2EAAAADAQAB..."""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('example.com', 'ssh-rsa', key)
with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
Though as of pysftp 0.2.9, this approach will issue a warning, what seems like a bug:
"Failed to load HostKeys" warning while connecting to SFTP server with pysftp
An easy way to retrieve the host key in the needed format is using OpenSSH ssh-keyscan:
$ ssh-keyscan example.com
# example.com SSH-2.0-OpenSSH_5.3
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...
(due to a bug in pysftp, this does not work, if the server uses non-standard port – the entry starts with [example.com]:port + beware of redirecting ssh-keyscan to a file in PowerShell)
You can also make the application do the same automatically:
Use Paramiko AutoAddPolicy with pysftp
(It will automatically add host keys of new hosts to known_hosts, but for known host keys, it will not accept a changed key)
Though for an absolute security, you should not retrieve the host key remotely, as you cannot be sure, if you are not being attacked already.
See my article Where do I get SSH host key fingerprint to authorize the server?
It's for my WinSCP SFTP client, but most information there is valid in general.
If you need to verify the host key using its fingerprint only, see Python - pysftp / paramiko - Verify host key using its fingerprint.
One option is to disable the host key requirement:
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
sftp.put(local_path, remote_path)
You can find more info about that here:
https://stackoverflow.com/a/38355117/1060738
Important note:
By setting cnopts.hostkeys=None you'll lose the protection against Man-in-the-middle attacks by doing so. Use #martin-prikryl answer to avoid that.
Try to use the 0.2.8 version of pysftp library.
$ pip uninstall pysftp && pip install pysftp==0.2.8
And try with this:
try:
ftp = pysftp.Connection(host, username=user, password=password)
except:
print("Couldn't connect to ftp")
return False
Why this?
Basically is a bug with the 0.2.9 of pysftp
here all details
https://github.com/Yenthe666/auto_backup/issues/47
Cook book to use different ways of pysftp.CnOpts() and hostkeys options.
Source : https://pysftp.readthedocs.io/en/release_0.2.9/cookbook.html
Host Key checking is enabled by default. It will use ~/.ssh/known_hosts by default. If you wish to disable host key checking (NOT ADVISED) you will need to modify the default CnOpts and set the .hostkeys to None.
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):
# do stuff here
To use a completely different known_hosts file, you can override CnOpts looking for ~/.ssh/known_hosts by specifying the file when instantiating.
import pysftp
cnopts = pysftp.CnOpts(knownhosts='path/to/your/knownhostsfile')
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):
# do stuff here
If you wish to use ~/.ssh/known_hosts but add additional known host keys you can merge with update additional known_host format files by using .load method.
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('path/to/your/extra_knownhosts')
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):
# do stuff here
If You try to connect by pysftp to "normal" FTP You have to set hostkey to None.
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection(host='****',username='****',password='***',port=22,cnopts=cnopts) as sftp:
print('DO SOMETHING')
Connect to the server first with a Windows ssh client that uses the known_hosts file.
PuTTy stores the data in the windows registry,however OpenSSH uses the known_hosts file, and will add entries in there after you connect.
Default location for the file is %USERPROFILE%.ssh. I hope this helps
I've implemented auto_add_key in my pysftp github fork.
auto_add_key will add the key to known_hosts if auto_add_key=True
Once a key is present for a host in known_hosts this key will be checked.
Please reffer Martin Prikryl -> answer about security concerns.
Though for an absolute security, you should not retrieve the host key remotely, as you cannot be sure, if you are not being attacked already.
import pysftp as sftp
def push_file_to_server():
s = sftp.Connection(host='138.99.99.129', username='root', password='pass', auto_add_key=True)
local_path = "testme.txt"
remote_path = "/home/testme.txt"
s.put(local_path, remote_path)
s.close()
push_file_to_server()
Note: Why using context manager
import pysftp
with pysftp.Connection(host, username="whatever", password="whatever", auto_add_key=True) as sftp:
#do your stuff here
#connection closed
Hi We sort of had the same problem if I understand you well. So check what pysftp version you're using. If it's the latest one which is 0.2.9 downgrade to 0.2.8.
Check this out. https://github.com/Yenthe666/auto_backup/issues/47
FWIR, if authentication is only username & pw, add remote server ip address to known_hosts like ssh-keyscan -H 192.168.1.162 >> ~/.ssh/known_hosts for ref https://www.techrepublic.com/article/how-to-easily-add-an-ssh-fingerprint-to-your-knownhosts-file-in-linux/

How to connect to Droxbox via sftp Python?

I want to send/download file from Droxbox via Python. I've tried pysftp and paramiko, but the connect() call will hang. Below is my code.
import paramiko
# create a client
ssh = paramiko.SSHClient()
# can alos choose .WarningPolicy(), .RejectPolicy()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="dropbox.com", username="my username", password="my pw")
# The call will hang there
sftp code
import pysftp as sftp
cnopts = sftp.CnOpts()
cnopts.hostkeys = None
'''If I don't set up cnopts, I'll get error - No hostkey for host dropbox.com found.
But I got a warning if I set up the above cnopts -
CryptographyDeprecationWarning: Support for unsafe construction of
public numbers from encoded data will be removed in a future
version. Please use EllipticCurvePublicKey.from_encoded_point
self.ecdsa_curve.curve_class(), pointinfo
'''
s = sftp.Connection(host="dropbox.com",
username="xi#transcriptic.com",
password="Python#2018",
cnopts=cnopts)
Any suggestions would be greatly appreciated!
I don't believe that Dropbox supports SFTP, sadly.

Python: Make SFTP connection using proxyhost and proxyport

I have trying to make a SFTP connection using a proxy
and print out the files in the SFTP directory
import pysftp
myHostname = "some.hostname.com"
myUsername = "test"
myPassword = "password"
myProxyHost = "10.10.10.10"
myProxyPort = "1010"
with pysftp.Connection(
host=myHostname,
username=myUsername,
password=myPassword,
proxy=myProxyHost,
proxyport=myProxyPort,
) as sftp:
print("Connection succesfully stablished ... ")
# Switch to a remote directory
sftp.cwd("/test/folder")
directory_structure = sftp.listdir_attr()
# Print data
for attr in directory_structure:
print(attr.filename, attr)
but I am getting a error of 'TypeError: init() got an unexpected keyword argument 'proxy''
could someone show me how to use proxy to make a successful connection.
Based on pysftp.Connection()'s documentation, it does not support proxy or proxyport parameters.
You may have better luck using the underlying Paramiko SFTPClient class – there's a gist over here that seems to have an explanation about proxying with Paramiko.

How to connect to SFTP through Paramiko with SSH key - Pageant

I am trying to connect to an SFTP through Paramiko with a passphrase protected SSH key. I have loaded the key into Pageant (which I understand is supported by Paramiko) but I can't get it to decrypt my private key.
I have found this example here that references allow_agent=True but this does not appear to be a parameter that can be used with the SFTPClient.
Can anyone advise if it is possible to work with Paramiko and Pageant in this way?
This is my code at the moment - which raises PasswordRequiredException
privatekeyfile = 'path to key'
mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile)
transport = paramiko.Transport(('host', 'port'))
transport.connect('username',pkey = mykey)
sftp = paramiko.SFTPClient.from_transport(transport)
You have to provide a passphrase, when loading an encrypted key using the RSAKey.from_private_key_file.
Though note that you do not have to load the key at all, when using the Pageant. That's the point of using an authentication agent. But only the SSHClient class supports the Pageant. The Transport class does not, on its own.
You can follow the code in How to use Pageant with Paramiko on Windows?
Though as the allow_agent is True by default, there is actually nothing special about the code.
Once connected and authenticated, use the SSHClient.open_sftp method to get your instance of the SFTPClient.
ssh = paramiko.SSHClient()
ssh.connect(host, username='user', allow_agent=True)
sftp = ssh.open_sftp()
You will also need to verify the host key:
Paramiko "Unknown Server"
This worked for me
privatekeyfile = 'path to key'
mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile)
ssh_client = paramiko.SSHClient()
ssh_client.load_system_host_keys()
ssh_client.connect(hostname='host', username='user', allow_agent=True, pkey=mykey)
ftp_client = ssh_client.open_sftp()
print(ftp_client.listdir('/'))

Categories

Resources