小白求助,请教如何使用paramiko来连接设备并发送命令

小白求助,目前如果使用power shell或者centos的shell里,去执行命令一切是正常的


然后我希望把这个流程使用paramiko来代替我实现,这样我可以后续通过程序周期性的上来选择一些设备执行命令。我的理解是,先用paramiko连接上我的jumpserver的koko,然后按提示符的回显来敲入设备选择,以及填入命令。我的代码如下
import paramiko
import time

def handler(title, instructions, prompt_list):
return [jumpserver_password]

定义读取回显的函数

def read_channel(channel, prompt, timeout=10):
output = “”
end_time = time.time() + timeout
while time.time() < end_time:
if channel.recv_ready():
output += channel.recv(1024).decode(‘utf-8’)
if prompt in output:
break
time.sleep(0.1)
return output

定义Jumpserver信息

jumpserver_ip = ‘myserver-ip’
jumpserver_port = 2222
jumpserver_user = ‘jmpuser’
jumpserver_password = ‘jmppass’

初始化Transport

trans = paramiko.Transport((jumpserver_ip, jumpserver_port))
trans.start_client()

try:
# 尝试使用password认证
trans.auth_password(jumpserver_user, jumpserver_password)
except paramiko.AuthenticationException:
# 如果password认证失败,尝试使用keyboard-interactive认证
trans.auth_interactive(jumpserver_user, handler)

打开一个通道并启动shell

channel = trans.open_session()
channel.get_pty()
channel.invoke_shell()
time.sleep(2) # 确保shell已启动

读取初始回显(可能有欢迎信息)

output = read_channel(channel, “password:”)
print(f"输出1:{output}")

发送密码

channel.send(jumpserver_password + ‘\n’)
output = read_channel(channel, 'Opt> ')
print(f"输出2:{output}")

发送选择命令 ‘1’,并读取输出

channel.send(‘1\n’)
output = read_channel(channel, '[Host]> ') # 假设业务服务器提示符是 ‘[Host]>’
print(f"输出3:{output}")

发送命令 ‘ifconfig’,并读取输出

channel.send(‘clock\n’)
output = read_channel(channel, '# ') # 假设业务服务器提示符是 ‘#’
print(f"输出4:{output}")

关闭通道和连接

channel.close()
trans.close()
目前代码运行时,有些问题,我的回显如下:
输出1: jmpuser, JumpServer 开源堡垒机

1) 输入 部分IP,主机名,备注 进行搜索登录(如果唯一).
2) 输入 / + IP,主机名,备注 进行搜索,如:/192.168.
3) 输入 p 进行显示您有权限的资产.
4) 输入 g 进行显示您有权限的节点.
5) 输入 h 进行显示您有权限的主机.
6) 输入 d 进行显示您有权限的数据库.
7) 输入 k 进行显示您有权限的Kubernetes.
8) 输入 r 进行刷新最新的机器和节点信息.
9) 输入 s 进行中文-English-日本語语言切换.
10) 输入 ? 进行显示帮助.
11) 输入 q 进行退出.

Opt>
输出2:jmppass
输出3:1
输出4:clock
貌似程序无法在Opt>后输入1这些信息,也无法捕获到任何回显了,请问这是为什么,我应该如何调整。

你想要的是连过堡垒机后指定资产然后输入命令,返回信息吗?不妨用接口做吧,可以看下http://your_jumpserver_ip/api/docs

断点去debug

我去看了这个/api/docs,感觉工作流程还是不太明白,我去搜索并试了些接口,目前勉强可以用了,我的流程是
step1: /ops/jobs/ 去创建临时的命令的job,得到一个task_id
step2: /ops/job-execution/task-detail/{task_id}/ 执行刚刚得到的task_id
但是这个流程感觉也不完善,step2得到的response基本都是running或者success这类,没有看见SSH资产给的回显。比如我去执行clock,就看不到类似
Fri 02 Aug 2024 03:36:27 AM CST -0.833412 seconds 这种回显
我问了下文档里的AI助手,它给我了一个比较符合逻辑的方案,




但是我找不到它说的这些API接口分别在哪里,我目前找到了一个创建session的地方
/terminal/sessions 我在这里创建了session之后,确实可以在“审计台”–“会话审计”–“在线会话”发现新建了一个会话,我的推测第二步应该是
/terminal/commands/ 我向这个接口post了session-id和input命令等数据,但是401报错, 也不知道是怎么了,

{
  "msg": "Command not valid: {'non_field_errors': [ErrorDetail(string='期望为一个包含物件的列表,得到的类型是“dict”。', code='not_a_list')]}"
}

然后AI助手说的第三个获得回显的API,我也找不到具体是哪个。

GET /api/v1/sessions/YOUR_SESSION_ID/commands/LATEST_COMMAND_ID/output/

我的需求就是,通过API或者paramiko等方式,利用程序去在assets里执行一些命令,再次请教各位大神,我这种情况具体应该使用哪些API接口?


或者说 不用api 是不是这个也能满足你的需求

1 个赞

这个是我最开始试过的方案,但是这个方案有一个问题是,只能通过ssh jmp-user@asset-user@asset-ip@jmp-ip -p 2222连接上登录方式为ssh的asset,如果asset是telnet方式登录,用这个命令我这边测试是无法连接上远端asset的。
我是个网络工程师,assets有些是ssh登录,有些太老了只能telnet,所以一开始想用paramiko来模拟手工登录koko并且选择设备发送命令来着。

我是一个网络工程师,我希望让程序定期或者按需调度(而不是手动)去登录某些资产,执行一些网络操作命令。
我之前刷别人的帖子,他推荐的也是跟您这个图片里的方案一样的,在“工作台” “作业中心” 创建一个“快捷命令”的作业并且执行它,所以我留意了一下页面URL然后去找api手册,测试出了那个半拉子api接口:
step1: /ops/jobs/ 去创建临时的命令的job,得到一个task_id
step2: /ops/job-execution/task-detail/{task_id}/ 执行刚刚得到的task_id
我目前这个流程卡在了step2的response里是没有cmd执行的output回显的。在“工作台” “作业中心” 执行完“快捷命令”后,是有一个叫“执行历史”的,里面有输出内容,我按照URL去猜测可能是
/ops/celery/task/{name}/task-execution/{id}/log/
或者/ops/celery/task/{name}/task-execution/{id}/result/
可是这两个都需要提供一个name,而我不知道name是什么,所以接着往下做不了了。

我刚刚试出来了,目前流程基本可以跑通了
step1 创建命令: /ops/jobs/ 去创建临时的命令的job,得到一个task_id
step2 执行命令: /ops/job-execution/task-detail/{task_id}/ 执行刚刚得到的task_id
step3 获得回显: /ops/celery/task/{name}/task-execution/{id}/log/ 这里面要提供的name和id都是刚刚的task_id
这样就可以了。但是目前这个也有个比较大的问题,就是只有ssh的asset可以被执行,如果是telnet的就会报错连不上。


而我如果用web的luna去执行是没有问题的

感觉这个/opt/job背后还是类似调用的koko模块里的ssh jmpuser@asset-user@asset-ip@jmp-ip -p 2222这种方式在执行,而luna的执行或者ssh到koko后再去选择asset的调用是不一样。