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

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('/'))

Related

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.

How to sftp connect through Paramiko with public key - python [duplicate]

I'm using Paramiko to connect through SSH to a server.
Basic authentication works well, but I can't understand how to connect with public key.
When I connect with PuTTY, the server tell me this:
Using username "root".
Authenticating with public key "rsa-key#ddddd.com"
Passphrase for key "rsa-key#ddddd.com": [i've inserted the passphrase here]
Last login: Mon Dec 5 09:25:18 2011 from ...
I connect to it with this ppk file:
PuTTY-User-Key-File-2: ssh-rsa
Encryption: aes256-cbc
Comment: rsa-key#dddd.com
Public-Lines: 4
[4 lines key]
Private-Lines: 8
[8 lines key]
Private-MAC: [hash]
With basic auth the error I get (from the log) is:
DEB [20111205-09:48:44.328] thr=1 paramiko.transport: userauth is OK
DEB [20111205-09:48:44.927] thr=1 paramiko.transport: Authentication type (password) not permitted.
DEB [20111205-09:48:44.927] thr=1 paramiko.transport: Allowed methods: ['publickey', 'gssapi-with-mic']
I've tried to include that ppk file and set to auth_public_key, but didn't work.
Can you help me?
Ok #Adam and #Kimvais were right, Paramiko cannot parse .ppk files.
So the way to go (thanks to #JimB too) is to convert .ppk file to OpenSSH private key format; this can be achieved using PuTTYgen as described here.
Then it's very simple getting connected with it:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('<hostname>', username='<username>', password='<password>', key_filename='<path/to/openssh-private-key-file>')
stdin, stdout, stderr = ssh.exec_command('ls')
print stdout.readlines()
ssh.close()
For me I doing this:
import paramiko
hostname = 'my hostname or IP'
myuser = 'the user to ssh connect'
mySSHK = '/path/to/sshkey.pub'
sshcon = paramiko.SSHClient() # will create the object
sshcon.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # no known_hosts error
sshcon.connect(hostname, username=myuser, key_filename=mySSHK) # no passwd needed
works for me pretty ok
To create a valid DSA format private key supported by Paramiko in Puttygen.
Click on Conversions then Export OpenSSH Key
#VonC's answer to (deleted) duplicate question:
If, as commented, Paraminko does not support PPK key, the official solution, as seen here, would be to use PuTTYgen.
But you can also use the Python library CkSshKey to make that same conversion directly in your program.
See "Convert PuTTY Private Key (ppk) to OpenSSH (pem)"
import sys
import chilkat
key = chilkat.CkSshKey()
# Load an unencrypted or encrypted PuTTY private key.
# If your PuTTY private key is encrypted, set the Password
# property before calling FromPuttyPrivateKey.
# If your PuTTY private key is not encrypted, it makes no diffference
# if Password is set or not set.
key.put_Password("secret")
# First load the .ppk file into a string:
keyStr = key.loadText("putty_private_key.ppk")
# Import into the SSH key object:
success = key.FromPuttyPrivateKey(keyStr)
if (success != True):
print(key.lastErrorText())
sys.exit()
# Convert to an encrypted or unencrypted OpenSSH key.
# First demonstrate converting to an unencrypted OpenSSH key
bEncrypt = False
unencryptedKeyStr = key.toOpenSshPrivateKey(bEncrypt)
success = key.SaveText(unencryptedKeyStr,"unencrypted_openssh.pem")
if (success != True):
print(key.lastErrorText())
sys.exit()

How to SSH from one system to another using python

I am trying to perform SSH from one system to another using paramiko in python
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
ssh.connect('127.0.0.1', username='jesse',
password='lol')
using this reference (http://jessenoller.com/blog/2009/02/05/ssh-programming-with-paramiko-completely-different )
This is the case when we know the password of the system you want to log-in BUT
if i want to login to a system where my public-key is copied and i dont know the password. Is there a way to do this
Thanks in advance
SSHClient.connect accepts a kwarg key_filename, which is a path to the local private key file (or files, if given a list of paths). See the docs.
key_filename (str) – the filename, or list of filenames, of optional private key(s) to try for authentication
Usage:
ssh.connect('<hostname>', username='<username>', key_filename='<path/to/openssh-private-key-file>')
This code should work:
import paramiko
host = "<your-host>"
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, username='<your-username>', key_filename="/path/to/.ssh/id_rsa" , port=22)
# Just to test a command
stdin, stdout, stderr = client.exec_command('ls')
for line in stdout.readlines():
print line
client.close()
Here is the documentation of SSHClient.connect()
EDIT : /path/to/.ssh/id_rsa is your private key!
Adding the key to a configured SSH agent would make paramiko use it automatically with no changes to your code.
ssh-add <your private key>
Your code will work as is. Alternatively, the private key can be provided programmatically with
key = paramiko.RSAKey.from_private_key_file(<filename>)
SSHClient.connect(pkey=key)

Is there a way using Paramiko and Python to get the banner of the SSH server you connected to?

Is there a way using Paramiko and Python to get the banner of the SSH server you attempt to connect to?
I am dealing with an ultra secure server setup process for many machines and the passwords are generated via a predefined cipher key which get's printed out at with the SSH banner. I have access to the utility that will give me the password, but I need the text in the banner to actually generate the initial password.
Looks like this wasn't a feature. Good thing I requested it and the totally awesome developers put it in...
https://github.com/paramiko/paramiko/issues/273
# !/usr/bin/python
import paramiko
def grab_banner(ip_address, port):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(ip_address, port=port, username='username', password='bad-password-on-purpose')
except:
return client._transport.get_banner()
if __name__ == '__main__':
print grab_banner('192.168.1.26', 22)

How to use Pageant with Paramiko on Windows?

I know that Paramiko supports Pageant under Windows, but it doesn't work by default.
I am looking for an example of connecting using the key that is loaded in Pageant.
This is what I am using to connect and do an automated login using Pageant to store my key, and connecting to it from within my Python script. It counts on Pageant already being loaded, (and I haven't found a good reliable way to launch it and load the key (prompt for key password)) but the below works for now.
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
host = 'somehost.com'
port = 22
ssh.connect(host, port=port, username='user', allow_agent=True)
stdin,stdout,stderr = ssh.exec_command("ps -ef")
print stdout.read()
print stderr.read()

Categories

Resources