诈尸。
终于轮到了一个“不费力但讨好”的项目,做的差不多了。随便翻翻feedly,看到有老司机在介绍开源堡垒机——jumpserver。
想了解实现原理,所以看了部分核心代码,这篇文章就是个简单的记录。
jumpserver三大核心组件:Jumpserver(Web控制台)、Luna(Web Terminal)、Coco(跳板机,即SSH Terminal)。
Coco为跳板机的守护进程,负责监听用户连接、鉴权、连接后端机器、监控命令等。这次只关注这个模块的实现原理。
相关目录结构:
coco/
app.py
interactive.py
interface.py
proxy.py
tasks.py
...
jms/
service.py
tasks.py
utils.py
...
run_server.py
run_server.py 为入口程序,会启动三个守护进程:
coco/app.py: 提供ssh连接服务
command_task: command_queue队列消费者,用户输入命令后发送到Jumpserver保存,用于后续审计
record_task: record_queue队列消费者,将输入输出发送给Jumpserver, 用来录像回放
跟进 app.py 的详细步骤:
开启socket监听,默认为2222端口,最多允许5个客户连接到服务器
每接收到一个客户端连接请求,就会开启一个新的守护线程,调用paramiko模块,假装自己是一个ssh server,进行ssh认证和建立连接
验证成功后,会开启一个交互式的命令窗口接收用户输入
用户输入机器ip后,程序会先判断是否为用户被授权的资产(调用接口查询数据库)。
如果查询到资产后,会再次调用paramiko模块,假装自己是client连接到后端机器(调用接口查询用户密码信息,然后连接)
利用多路复用IO的模块(python selectors)来监控两边的输入输出,并进行双向通信。如下(糙)图:
堡垒机在这里完全可以理解为一个代理。从始至终,你都没有真正连接到你的开发机的terminal。堡垒机先读取用户输入,做一些不可见人的事情(命令监控)后,发送给指定的开发机,然后读取开发机的输出,再输出给用户。
弄清楚这个过程之前,需要区分几个概念:
Interactive Console: 交互式命令行,常见的有 Chrome Console
、Python Console
、 Linux Terminal
等
SSH: 只是一个通信协议,经常用来连接Linux Terminal
Linux Terminal: 交互式命令行的一种
ssh连接堡垒机,实际只是连接到了堡垒机的某个守护进程的交互式命令行,跟堡垒机的Linux Terminal没有关系,堡垒机的 /etc/passwd 中也没有你的账号。
选择了开发机并连接成功后,和你进行交互的还是堡垒机的交互式命令行。堡垒机通过SSH连接到了开发机的Linux Terminal,读取你的输入发送给开发机的Terminal,然后再读取Terminal的输出发送给你。
有续篇还是没续篇,这是一个问题。
jumpserver: https://github.com/jumpserver/jumpserver/wiki/v0.4.0-%E5%BA%94%E7%94%A8%E5%9B%BE%E8%A7%A3