我试图使用Paramiko(在Python 2.7上)连接到使用多因素身份验证的主机(用户名+密码+一次性密码)。 transport.auth_interactive函数似乎是这样做的方式(基于我对文档的理解),但执行永远不会达到这一点 - 在client.connect行上验证失败。
我似乎错过了什么。
这是代码:
#!/usr/bin/env python
import paramiko
import getpass
import os
import logging
user = ""
pw = ""
mfa = ""
def inter_handler(title, instructions, prompt_list):
resp = []
for pr in prompt_list:
if pr[0].strip() == "Username:":
resp.append(user)
elif pr[0].strip() == "Password:":
resp.append(pw)
elif pr[0].strip() == "OTP Code:":
resp.append(mfa)
return tuple(resp)
#Main Entry Point
if __name__ == "__main__":
paramiko.util.log_to_file(os.path.expanduser('~/paramiko.log'), logging.DEBUG)
user = raw_input("Username: ")
pw = getpass.getpass("Password: ")
mfa = raw_input("OTP Code:")
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #Don't care about host keys
client.connect("mfahost.example.com", port=22, username=user, password=pw, look_for_keys=False)
client.get_transport().auth_interactive(user, inter_handler)
client.exec_command("touch ~/paramikotestfile")
答案 0 :(得分:5)
回答我自己的问题,因为我设法解决了,并且认为我会分享。
简短的回答是,必须创建套接字,在其上创建Paramiko客户端传输,调用auth_interactive,然后打开会话。该会话提供了一个Paramiko Channel对象,可以像SSHClient对象一样执行exec_command调用。
以下代码是完整的参考实现:
#!/usr/bin/env python
False
答案 1 :(得分:1)
更方便的方法是auth_interactive_dumb方法。它是一个auth_interactive,仅将服务器要求的内容输出到控制台,然后将您键入的内容发回。这样,您不必存储密码,也不必编写自己的处理程序。
所以基本上
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("mfahost.example.com", 22))
ts = paramiko.Transport(sock)
ts.start_client(timeout=10)
ts.auth_interactive_dumb(user)