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()
Related
I'm trying to create a single file executable in Python and using Paramiko for my SSH. I need to eliminate external files such as private key files and try to go for embedded strings.
I tried this solution but it's not working for me:
Paramiko: Creating a PKey from a public key string
How do I accomplish this? Thanks.
The solution you mentioned:
key = paramiko.RSAKey(data=base64.b64decode('AAblablabla...'))
works fine however it may be inconvenient to store the key in base64 format.
The following code shows how to use the key stored in "plain-text" format (as key-files in ~/.ssh directory):
import paramiko
import StringIO
my_key = """\
-----BEGIN RSA PRIVATE KEY-----
<your key here>
-----END RSA PRIVATE KEY-----"""
pkey = paramiko.RSAKey.from_private_key(StringIO.StringIO(my_key))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='host', username='user', pkey=pkey)
...
ssh.close()
In Python 3:
import io
# ...
pkey = paramiko.RSAKey.from_private_key(io.StringIO(my_key))
See StringIO in Python3
I had the same issue where I'm trying to not have private key files using AWS secrets manager, just got it to work with the following. Notice the \n in the privatekey.
import io
privatekey = io.StringIO('-----BEGIN OPENSSH PRIVATE KEY-----\nRestOfTheKey\n-----END OPENSSH PRIVATE KEY-----')
pkey = paramiko.Ed25519Key.from_private_key(privatekey)
Then when you're connecting
aws_ssh = paramiko.SSHClient()
aws_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
aws_ssh.connect(hostname='YOURHOST', username='YOURUSERNAME', pkey=pkey)
Now, however, if you're like me and using this for Lambda+Secrets Manager, and the secrets manager has a key+value and you're pulling the value of this privatekey from there. One thing to note is that secrets manager will escape the \n and turn it into \\n. To fix that, modify the above code to replace the \\n to \n.
awskeytemp = secrets['YOURKEY'].replace('\\n', '\n')
privatekey = io.StringIO(awskeytemp)
pkey = paramiko.Ed25519Key.from_private_key(privatekey)
To add a public key from a string on the ssh client you must set the keyword arg look_for_keys=False then use the MissingHostKeyPolicy classes missing_host_key() method to add the key from your string.
my_pub_key = "xx.xx.xx.xx ecdsa-sha2-nistp256 mlzdHAyNT....."
my_host = my_pub_key.split(' ')[0]
password = 'myFavortitePassword'
username = 'myUsername'
ssh_client=paramiko.SSHClient()
host_key_policy = paramiko.MissingHostKeyPolicy()
host_key_policy.missing_host_key(ssh_client, my_host, my_pub_key)
ssh_client.connect(hostname= my_host
,username=username
,password=password
,port=22
,look_for_keys=False)
When I ran my python code (using parmiko library python) I got this error:
Bad authentication type; allowed types: ['publickey', 'gssapi-keyex',
'gssapi-with-mic']
The path I supplied was to a .pem file which was my key to the server.
How do I get a public key out of this .pem file not necessarily using python?
(I am using a mac)
Here is the code I used:
import paramiko
def file_move():
k = paramiko.RSAKey.from_private_key_file("Insertadress")
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
print ("connecting...")
c.connect(hostname = "inserthostname", username = None, password = "insert pw" ,pkey = k)
print ("connected!!!")
stdin, stdout, stderr = c.exec_command('ls')
c.close()
file_move()
Paramiko does not seem to have an API for extracting the public key from a private key, but since you are welcoming non-Python solutions too, here is a command line version:
ssh-keygen -y -f myprivatekey
where myprivatekey is the file containing your private key (named Insertaddress in the question).
This outputs the public key on standard output.
Tested on Linux (where the command is provided by the package openssh-client), but should work on a Mac too.
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)
I'm trying to create a single file executable in Python and using Paramiko for my SSH. I need to eliminate external files such as private key files and try to go for embedded strings.
I tried this solution but it's not working for me:
Paramiko: Creating a PKey from a public key string
How do I accomplish this? Thanks.
The solution you mentioned:
key = paramiko.RSAKey(data=base64.b64decode('AAblablabla...'))
works fine however it may be inconvenient to store the key in base64 format.
The following code shows how to use the key stored in "plain-text" format (as key-files in ~/.ssh directory):
import paramiko
import StringIO
my_key = """\
-----BEGIN RSA PRIVATE KEY-----
<your key here>
-----END RSA PRIVATE KEY-----"""
pkey = paramiko.RSAKey.from_private_key(StringIO.StringIO(my_key))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='host', username='user', pkey=pkey)
...
ssh.close()
In Python 3:
import io
# ...
pkey = paramiko.RSAKey.from_private_key(io.StringIO(my_key))
See StringIO in Python3
I had the same issue where I'm trying to not have private key files using AWS secrets manager, just got it to work with the following. Notice the \n in the privatekey.
import io
privatekey = io.StringIO('-----BEGIN OPENSSH PRIVATE KEY-----\nRestOfTheKey\n-----END OPENSSH PRIVATE KEY-----')
pkey = paramiko.Ed25519Key.from_private_key(privatekey)
Then when you're connecting
aws_ssh = paramiko.SSHClient()
aws_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
aws_ssh.connect(hostname='YOURHOST', username='YOURUSERNAME', pkey=pkey)
Now, however, if you're like me and using this for Lambda+Secrets Manager, and the secrets manager has a key+value and you're pulling the value of this privatekey from there. One thing to note is that secrets manager will escape the \n and turn it into \\n. To fix that, modify the above code to replace the \\n to \n.
awskeytemp = secrets['YOURKEY'].replace('\\n', '\n')
privatekey = io.StringIO(awskeytemp)
pkey = paramiko.Ed25519Key.from_private_key(privatekey)
To add a public key from a string on the ssh client you must set the keyword arg look_for_keys=False then use the MissingHostKeyPolicy classes missing_host_key() method to add the key from your string.
my_pub_key = "xx.xx.xx.xx ecdsa-sha2-nistp256 mlzdHAyNT....."
my_host = my_pub_key.split(' ')[0]
password = 'myFavortitePassword'
username = 'myUsername'
ssh_client=paramiko.SSHClient()
host_key_policy = paramiko.MissingHostKeyPolicy()
host_key_policy.missing_host_key(ssh_client, my_host, my_pub_key)
ssh_client.connect(hostname= my_host
,username=username
,password=password
,port=22
,look_for_keys=False)
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('/'))