远程服务器使用Duo2因素身份验证,并在使用SSH连接时提示您选择身份验证模式:
$ ssh myuser@remoteserver.com
Duo two-factor login for myuser
Enter a passcode or select one of the following options:
1. Duo Push to +XXX XX-XXX-1111
2. Phone call to +XXX XX-XXX-1111
3. SMS passcodes to +XXX XX-XXX-1111
Passcode or option (1-3): 1
Success. Logging you in...
当我在终端中使用ssh时,我只需按1然后输入,得到我的手机的推送,在那里我证明了连接,然后我就登录了。
不幸的是,我无法在Python中做到这一点。下面是我尝试使用的代码:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('remoteserver.com', port=22, username='myuser', password='mypassword')
stdin, stdout, stderr = ssh.exec_command('ls -l')
output = stdout.readlines()
print(output)
paramiko.ssh_exception.AuthenticationException: Authentication failed.
如有任何帮助,将不胜感激。
在我的一个项目中,我自己终于解决了这个问题,将留下我所使用的代码,它允许进行这项工作。
主要的特点是,paramiko允许在传输和提示列表中这样做,在我的示例中,我的two_factor_types
中缺少publickey方法
def _auth(self, username, password, pkey, *args):
self.password = password
saved_exception = None
two_factor = False
allowed_types = set()
two_factor_types = {'keyboard-interactive', 'password', 'publickey'}
参考文献:
paramiko/python:键盘交互身份验证
https://github.com/paramiko/paramiko/pull/467
https://github.com/paramiko/paramiko/pull/467/commits/dae916f7bd6723cee95891778baff51ef45532ee
http://docs.paramiko.org/en/stable/api/transport.html
我建议尝试使用auth_interactive_dumb这样的方法
auth_interactive_dumb(username, handler=None, submethods='')
以交互方式向服务器进行身份验证,但比较笨拙。只需将提示和/或说明打印到stdout并发回响应。这对于通过密钥实现部分身份验证,然后用户必须输入2fac令牌的情况很好。
有关更多完整示例,请参阅下面的摘录和链接
class SSHClient(paramiko.SSHClient):
duo_auth = False
def handler(self, title, instructions, prompt_list):
answers = []
global duo_auth
if title.startswith('Duo two-factor login'):
duo_auth = True
raise SSHException("Expecting one field only.")
for prompt_, _ in prompt_list:
prompt = prompt_.strip().lower()
if prompt.startswith('password'):
answers.append(self.password)
elif prompt.startswith('verification'):
answers.append(self.totp)
elif prompt.startswith('passcode'):
answers.append(self.totp)
else:
raise ValueError('Unknown prompt: {}'.format(prompt_))
return answers
def auth_interactive(self, username, handler):
if not self.totp:
raise ValueError('Need a verification code for 2fa.')
self._transport.auth_interactive(username, handler)
def _auth(self, username, password, pkey, *args):
self.password = password
saved_exception = None
two_factor = False
allowed_types = set()
two_factor_types = {'keyboard-interactive', 'password', 'publickey'}
agent = paramiko.Agent()
try:
agent_keys = agent.get_keys()
# if len(agent_keys) == 0:
# return
except:
pass
for key in agent_keys:
logging.info("Trying ssh-agent key %s" % hexlify(key.get_fingerprint()))
try:
self._transport.auth_publickey(username, key)
logging.info("... success!")
return
except paramiko.SSHException as e:
logging.info("... nope.")
saved_exception = e
if pkey is not None:
logging.info('Trying publickey authentication')
try:
allowed_types = set(
self._transport.auth_publickey(username, pkey)
)
two_factor = allowed_types & two_factor_types
if not two_factor:
return
except paramiko.SSHException as e:
saved_exception = e
if duo_auth or two_factor:
logging.info('Trying 2fa interactive auth')
return self.auth_interactive(username, self.handler)
if password is not None:
logging.info('Trying password authentication')
try:
self._transport.auth_password(username, password)
return
except paramiko.SSHException as e:
saved_exception = e
allowed_types = set(getattr(e, 'allowed_types', []))
two_factor = allowed_types & two_factor_types
assert saved_exception is not None
raise saved_exception
问题内容: 我尝试过的 然后 再发送密码导致没有root 然后导致“频道关闭”错误 然后导致不被root 然后写到标准输入并刷新它导致没有root 问题答案: 看看这个例子: 在此处找到具有更多说明的示例:http : //jessenoller.com/2009/02/05/ssh- programming-with-paramiko-completely- different/ 希望能帮助到你
问题内容: 我想编写一个程序(在Windows 7的Python 3.x中),通过ssh在远程shell上执行多个命令。在查看了paramikos的功能之后,我意识到它不适合我的用例(因为在执行命令后通道被关闭了),因为这些命令取决于环境变量(由先前的命令设置),并且不能被合并为一个调用它们,因为它们将在程序中的不同时间执行。 因此,我想在同一通道中执行命令。我研究的下一个选项是使用paramik
本文向大家介绍Python paramiko使用方法代码汇总,包括了Python paramiko使用方法代码汇总的使用技巧和注意事项,需要的朋友参考一下 1、用户名、密码登陆方式 2、免密登陆方式 注意:生成密码的方法 A、进入本地 ssh文件夹 cd .ssh/ B、使用ssh-keygen生产本地公钥和私钥 ssh-keygen xueerhuan@ubuntu:~/.ssh$ ls id_
问题内容: 我正在学习python。我需要使用隧道创建者来从数据库中读取信息并关闭隧道。我使用paramiko,但是我没有使用tonelem示例。请举一个创建隧道的简单代码示例。 提前致谢! 问题答案: 在工作中,我们通常创建ssh隧道转发端口。我们的方法是使用标准命令,使子进程在单独的线程中运行。我找到了这个有用的链接:https : //github.com/paramiko/paramiko
本文向大家介绍Python如何使用paramiko模块连接linux,包括了Python如何使用paramiko模块连接linux的使用技巧和注意事项,需要的朋友参考一下 python程序需要连接linux时,需要使用密码或者秘钥验证以登录os进行命令操作或者文件传输,python中实现此功能的模块为paramiko;下面是该模块的基础用法 下面是通过密码进行linux登录执行命令和文件传输示例
问题内容: 我想使用python自动执行特定任务。 除其他事项外,此任务包括使用ssh连接到远程服务器,以及运行 可能会或可能不会要求用户输入* 的特定程序(称为它)。 经过一些研究并权衡了我的选择之后,我决定使用Python的Paramiko(考虑到以下因素,结果可能是错误的)。 * 让我们从不询问任何输入的简单可能性开始,而只是将一些信息打印到控制台: 编译为:,位于 server_name上