使用paramiko进行多重身份验证(密码和密钥)

时间:2015-03-03 16:38:08

标签: python sftp paramiko

我有以下代码:

import paramiko
policy = paramiko.client.WarningPolicy()
client = paramiko.client.SSHClient()
client.set_missing_host_key_policy(policy)
username = '...'
password = '...'
file_path = '...'
pkey = paramiko.RSAKey.from_private_key_file(file_path)
client.connect('...', username=username, password=password, pkey=key)
sftp = client.open_sftp() 

从文档来看,它似乎应该有效。一切正常,但是当代码命中client.open_sftp时,它会以SSHException: Unable to open channel.进行轰炸,并且传输(来自client.get_transport)处于活动状态但未经过身份验证。我也无法为此启用调试日志记录(我正在尝试logging.getLogger('paramiko').setLevel(logging.DEBUG)但没有成功。)

关于我可以开始调试这个非常模糊的错误消息的任何想法?

2 个答案:

答案 0 :(得分:1)

在您的脚本中声明

pkey = paramiko.RSAKey.from_private_key_file(file_path)

然后代替pkey,你有pkey = key

不确定来自哪个密钥,但这可能是一个问题。

答案 1 :(得分:0)

对不起,您的回复很晚,但是这个问题真的很难找到任何信息,因此我想为所有坚持此问题的人发布解决方案。

在努力解决这个问题后,我发现了一个解决方案,这要归功于Doug Ellwanger和Daniel Brownridge发布的一些代码。该问题似乎是由使用更多交互样式来处理多因素身份验证的方式引起的。

username = '...'
password = '...'
file_path = '...'
pkey = paramiko.RSAKey.from_private_key_file(file_path)
sftpClient = multifactor_auth('...', 22, username, pkey, password)

...

def multifactor_auth_sftp_client(host, port, username, key, password):
    #Create an SSH transport configured to the host
    transport = paramiko.Transport((host, port))
    #Negotiate an SSH2 session
    transport.connect()
    #Attempt authenticating using a private key
    transport.auth_publickey(username, key)
    #Create an event for password auth
    password_auth_event = threading.Event()
    #Create password auth handler from transport
    password_auth_handler = paramiko.auth_handler.AuthHandler(transport)
    #Set transport auth_handler to password handler
    transport.auth_handler = password_auth_handler
    #Aquire lock on transport
    transport.lock.acquire()
    #Register the password auth event with handler
    password_auth_handler.auth_event = password_auth_event
    #Set the auth handler method to 'password'
    password_auth_handler.auth_method = 'password'
    #Set auth handler username
    password_auth_handler.username = username
    #Set auth handler password
    password_auth_handler.password = password
    #Create an SSH user auth message
    userauth_message = paramiko.message.Message()
    userauth_message.add_string('ssh-userauth')
    userauth_message.rewind()
    #Make the password auth attempt
    password_auth_handler._parse_service_accept(userauth_message)
    #Release lock on transport
    transport.lock.release()
    #Wait for password auth response
    password_auth_handler.wait_for_response(password_auth_event)
    #Create an open SFTP client channel
    return transport.open_sftp_client()

我希望这对我的项目有用。