2013-03-22 11 views
13

Ich versuche Paramiko verwenden, um eine Verbindung zu einem SSH-Server von Python herzustellen. Dies ist, was ich bisher versucht habe:Paramiko - mit verschlüsselten privaten Schlüsseldatei unter OS X

>>> import paramiko 
>>> import os 
>>> privatekeyfile = os.path.expanduser('~/.ssh/id_rsa') 
>>> mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/pkey.py", line 198, in from_private_key_file 
    key = cls(filename=filename, password=password) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/rsakey.py", line 51, in __init__ 
    self._from_private_key_file(filename, password) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/rsakey.py", line 163, in _from_private_key_file 
    data = self._read_private_key_file('RSA', filename, password) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/pkey.py", line 280, in _read_private_key_file 
    data = self._read_private_key(tag, f, password) 
    File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/pkey.py", line 323, in _read_private_key 
    raise PasswordRequiredException('Private key file is encrypted') 
paramiko.PasswordRequiredException: Private key file is encrypted 

Wie Sie sehen können, scheitert es, weil mein privater Schlüssel verschlüsselt ist. Das Passwort wird jedoch in meinem OS X-Login-Schlüsselbund gespeichert, und wenn ich ssh host tippe, wird es nicht danach fragen (es fragt nur einmal, dann merkt es sich das bis zum nächsten Neustart). Gibt es eine Möglichkeit, paramiko verwenden Sie das Passwort/holen Sie es aus dem Schlüsselbund, wie ssh tut?

Antwort

7

Die RSAKey.from_private_key_file() ist vererbt von PKey(); Ein optionaler Parameter dieser Methode ist ein Passwort. Zu zitieren:

Wenn der private Schlüssel verschlüsselt und Passwort ist nicht ohne, das angegebene Passwort verwendet werden, um den Schlüssel zu entschlüsseln (sonst PasswordRequiredException geworfen).

Da Sie kein Passwort weitergeben und Ihr Schlüssel verschlüsselt ist, wird diese Ausnahme immer ausgelöst. Um dieses Problem zu umgehen, gibt es nur eine Möglichkeit, der Methode ein Passwort zu geben. Sie benötigen daher eine Möglichkeit, das Passwort aus der OSXKeychain zu entfernen.

Sie können dazu das plattformübergreifende Modul Keyring verwenden.

+0

Ich landete nur ein neues Schlüsselpaar, das kein Passwort hatte und das verwenden, aber das akzeptieren, da dies wahrscheinlich funktioniert hätte – houbysoft

+0

Das war meine eigene Lösung, wenn ich mit dieser Situation @houbysoft konfrontiert ... es einfach beantwortete die Frage nicht :-). – Ben

+0

Also, das Passwort wird als die Entschlüsselung der Passphrase verwendet? weil ich das gerade probiert habe und es nicht funktioniert hat! –

11

Der folgende Ansatz scheint gut zu funktionieren (auf OS X, mit dem üblichen Aufbau von verschlüsselten privaten Schlüssel, die Passwörter gespeichert in den Schlüsselbund, ohne Benutzerinteraktion haben):

import paramiko 

ssh = paramiko.SSHClient() 
ssh.load_system_host_keys() 
ssh.connect(HOST, username=USER, look_for_keys=False) 
... 
ssh.close() 

Es scheint, dass look_for_keys=False ist nicht unbedingt notwendig. Wenn Sie es jedoch verwenden, erhalten Sie wesentlich bessere Fehlermeldungen im Falle eines Authentifizierungsfehlers ("AuthenticationException" anstelle von "PasswordRequiredException").


Wenn Sie wirklich direkt private Schlüssel verwenden möchten, können Sie könnte folgendes tun:

import os 
import paramiko 
import keyring 

keyfile = os.path.expanduser('~/.ssh/id_rsa') 
password = keyring.get_password('SSH', keyfile) 
key = paramiko.RSAKey.from_private_key_file(keyfile, password=password) 

jedoch auf der Grundlage meiner Prüfung, dies ist nicht benötigt. Die obige Lösung, die einfach verwendet, sollte ausreichend sein.

+2

Ich erhalte diesen Fehler bei Ihrem ersten Ansatz: Keine Authentifizierungsmethoden verfügbar –