使用 Python pyotp 库实现 OTP两步认证 进行SSH自动登录

By | 2022年6月22日

工作中遇到一个棘手的任务,就是对接山石堡垒机,用 python通过 ssh 自动登录 帕拉迪堡垒机,然后跳转到指定防火墙设备去抓它配置,这本来不是问题,问题是客户的帕拉迪堡垒机设置了 OTP 认证,SSH登录密码是静态密码和 OTP token码的组合,密码也有一定的格式要求。

问题的核心在于如何让 python 程序自己生成 token?得到token后就简单了,只需将它和静态密码按一定格式组合下就变成 SSH登录密码了,然后用 python SSH登录,再用 pexpect 抓数据,后面功能都是现成的。

最终找到了一个 pyotp 的 python 库,完美解决问题!
OTP 是 One-Time Password的 简写,表示一次性密码,分为以下两种:

  • HOTP 是HMAC-based One-Time Password的简写,表示基于HMAC算法加密的一次性密码。
  • TOTP 是Time-based One-Time Password的简写,表示基于时间戳算法的一次性密码。

工作中用的是第二种 TOTP,每30秒产生一个新口令token,要求客户端和服务器能够十分精确的保持正确的时钟,客户端和服务端基于时间计算的动态口令才能一致。像谷歌验证器、Authy 这种APP上我们一般会看到每隔30秒换一个口令 ,如图:

现在要做的就是用 python pyotp库来替代这个 APP 生成 token,这里我直接附上 python 代码:

# -*- coding: utf-8 -*-

import pyotp

# 由于开发环境用的较旧 python 2.7,因此无法直接用最新的 pyotp,要指定 2.3.0及以下版本才行。
# pip install pyotp==2.3.0

# 下面地址从客户"获取opt认证"的二维码中解析而来,如果是谷歌验证器等APP直接扫二维码就好,这里要用后面的 secret 值。
# str = 'otpauth://totp/HD@test?secret=Y56G7QBTUDDHSNFV'

secretKey = 'Y56G7QBTUDDHSNFV'
print '>>> secret:', secretKey

totp = pyotp.TOTP(secretKey)
token = totp.now()
print '>>> token:', token

# 有了这个 token,就可以和静态密码组合,然后处理后续的 SSH 登录和 pexpect 交互抓数据了!

实际情况中,要连客户堡垒机还有一个要求,就是要先用VPN进入他们公司内网才行,且不支持 CentOS7 上安装,所以我选择在 Windows10 上装了VPN。但是使用 python pexpect 模块只能再 linux系统上,因此我又将 WMware 虚拟机桥接网络改成 NAT网络,此时虚拟机CentOS7 可以成功借助 Windows10 上的VPN 连到客户帕拉迪堡垒机了,截图如下:

在 pexpect 与设备交互抓数据过程中,使用 putty 等类似工具打印出原始日志,分析结尾符也是必不可少的,毕竟像 帕拉迪堡垒机这种设备 界面看到的字符都是特殊字符,得到的日志最好用 Nodepad++ 来打开分析。

发表评论

您的电子邮箱地址不会被公开。