如何用Paramiko通过需账号密码+RSA令牌的跳板机SSH访问思科设备
跳板机双重认证优化方案
你当前报错的核心原因是ssh.connect()方法默认会自动触发认证流程,后续再调用auth_interactive_dumb会出现认证状态冲突。针对账号密码+RSA动态令牌的双重认证场景,更灵活的方案是使用auth_interactive方法绑定自定义回调函数,自动匹配服务端的挑战提示返回对应凭证,示例代码如下:
import paramiko from paramiko import SSHException # 初始化SSH客户端 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 手动初始化传输层,避免默认自动认证 transport = paramiko.Transport(("jump_server_ip", 22)) transport.start_client() # 认证回调函数:按服务端返回的挑战提示返回对应凭证 def auth_challenge_handler(title, instructions, prompt_list): resp = [] for prompt, echo in prompt_list: # 匹配密码输入提示 if "password" in prompt.lower() or "密码" in prompt: resp.append("你的跳板机登录密码") # 匹配RSA动态令牌输入提示 elif "token" in prompt.lower() or "rsa" in prompt.lower() or "令牌" in prompt: resp.append("当前有效期内的RSA动态令牌值") return resp # 执行交互式认证 transport.auth_interactive( username="你的跳板机用户名", handler=auth_challenge_handler ) # 将认证完成的传输层绑定到SSH客户端实例 ssh._transport = transport
如果需要自动生成RSA令牌,可将令牌生成逻辑集成到回调函数中,无需手动填入固定值。
跳板机连接成功后访问思科设备的方案
你可以根据场景选择以下两种方案实现思科设备的SSH访问:
方案1:端口转发隧道(推荐)
该方案通过跳板机建立本地端口到思科设备的SSH隧道,本地可直接访问对应端口,操作逻辑和直连思科设备完全一致:
# 配置端口转发:本地127.0.0.1的2222端口流量将转发到思科设备的22端口 transport.request_port_forward("", 2222, "思科设备IP地址", 22) # 本地直接连接转发端口即可访问思科设备 cisco_ssh = paramiko.SSHClient() cisco_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) cisco_ssh.connect( hostname="127.0.0.1", port=2222, username="思科设备登录用户名", password="思科设备登录密码" ) # 执行思科命令示例 stdin, stdout, stderr = cisco_ssh.exec_command("show version") print(stdout.read().decode("utf-8", errors="ignore"))
方案2:跳板机会话内直连
如果跳板机关闭了端口转发权限,可直接在跳板机的交互式会话中发起SSH连接到思科设备:
# 激活跳板机交互式shell jump_shell = ssh.invoke_shell() jump_shell.settimeout(15) # 发送SSH连接思科设备命令 jump_shell.send("ssh 思科设备用户名@思科设备IP地址\n") # 等待密码输入提示 while not jump_shell.recv_ready(): pass output = jump_shell.recv(4096).decode("utf-8", errors="ignore") if "password" in output.lower(): jump_shell.send("思科设备登录密码\n") # 发送思科操作命令示例 jump_shell.send("show ip interface brief\n") while not jump_shell.recv_ready(): pass print(jump_shell.recv(4096).decode("utf-8", errors="ignore"))
内容的提问来源于stack exchange,提问作者Gurpreet Kochar
相关产品推荐
相关产品推荐

