使用 Paramiko 进行多因素身份验证(密码和密钥) [英] Multi-factor authentication (password and key) with 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)
没有成功.)
From the docs, it seems like it should work. Everything works successfully, but when the code hits client.open_sftp
it bombs with a SSHException: Unable to open channel.
and the transport (from client.get_transport
) is active but not authenticated. I'm also having trouble enabling debug logging for this (I'm trying logging.getLogger('paramiko').setLevel(logging.DEBUG)
without success.)
关于我可以从哪里开始调试这个非常模糊的错误消息的任何想法?
Any ideas on where I can start to debug this very vague error message?
推荐答案
很抱歉回复晚了,但这个问题真的很难找到任何信息,所以我想为其他陷入这个问题的人发布一个解决方案.
Sorry for the late response but this problem was really hard to find any information on so i wanted to post a solution for anyone else stuck on this issue.
>
在试图解决这个问题之后,我找到了一个解决方案,这要归功于 Doug Ellwanger 和 Daniel Brownridge 发布的一些代码.问题似乎是由使用更多交互样式处理多因素身份验证的方式引起的.
After pulling my hair out trying to solve this I found a solution thanks to some code posted by Doug Ellwanger and Daniel Brownridge. The problem seems to be caused by the way the multi-factor authentication is handled using more of an interactive style.
import paramiko
import threading
...
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()
我希望这会有所帮助,它适用于我的项目.
I hope this helps, it worked for my project.
这篇关于使用 Paramiko 进行多因素身份验证(密码和密钥)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!