jumpserver使用和二开记录

Posted by     "" on Wednesday, April 20, 2022

介绍

改造场景

公司的服务需要管理和登录全国各地的数百台边缘设备(服务器),而这些服务器往往部署在内网,无法访问。

运维同学首先提出了使用jumpserver堡垒机管理这些终端,因为其自带的权限管理、设备控制、日志审计等等功能十分完善,对于运维工作的开展较为便利。然而因为以上原因,运维同事常用的堡垒机jumpserver无法配置登录到目标设备。

经过考虑,若需要改造jumpserver并管理这些机器,需要满足几个条件:

  • 打通登录功能

    为了解决这个问题,我们结合了开源项目shellhub这一利器进行开发,这里引用官方readme简单介绍下shellhub:

    ShellHub is a modern SSH server for remotely accessing Linux devices via command line (using any SSH client) or web-based user interface, designed as an alternative to sshd. Think ShellHub as centralized SSH for the the edge and cloud computing.

    ShellHub 是一个现代化的 SSH 服务器,用于通过命令行(使用任何 SSH 客户机)或基于 web 的用户界面远程访问 Linux 设备,设计用于替代 sshd。可以将 ShellHub 看作是用于边缘和云计算的集中化 SSH。

    其背后使用了websocket做了长链接,将sshd的shell连接数据使用长链接的通道交换,从而建立起来一个登录效果,可以应用在web界面或者命令行等。具体细节可以点击项目链接跳转GitHub查看

  • 考虑设备量大的场景,未来可能数万台设备

    然而如果设备数量大了以后呢,一直保持着这种长链接可能对服务器造成压力,因为我们需要登录服务器的时间往往很少,一直保持长连接也是对服务器性能的一种浪费,我们需要一种机制:能够在需要连接目标终端的时候,打开长连接,在不需要连接的时候再次断开。

    解决方案:

    由于我们的系统里已经存在mqtt建立起来的消息中心,因此我们可以使用消息中心通知终端,令终端主动开启和关闭长连接

    最终连接的方式和普通的ssh连接类似:ssh root@ssh-cli.{服务器guid}@{消息中心服务地址}

    而我们需要做的就是:

    • 录入设备数据

      将shellhub连接参数,拼接成用户名的方式,录入到jumpserver系统中,比如 账号为:root@ssh-cli.{服务器guid},后半段的IP固定为{消息中心服务地址}即可。

      此处需要对接jumpserver API

    • 在jumpserver的连接发起前,单独调用接口,通过消息中心通知目标终端发起连接

      此处需要修改源码

  • 设备连接信息需要自动同步到jumpserver,不需要登录jumpserver手动操作

    为了减少运维工作量和精简上机流程,我们需要对接jumpserver接口,将上机过程中的数据从后台自动同步到jumpserver,以达到设备注册到后台的时候,自动出现在jumpserver系统中。

    好在jumpserver提供的swagger文档较为完善,我们一步步对接即可。

部署

使用官方文档提供的一键部署方案最省心,一直下一步即可。jumpserver包含的 组件,包括celery、lion、nginx、Koko、core等等,还提供了mysql和Redis可选的docker镜像安装,用户可以自行决定是否需要使用改镜像亦或者是单独部署。

开发

官方架构图

token

https://docs.jumpserver.org/zh/master/dev/rest_api/?h=token

接口文档:

直接点击查阅官方文档

我的是2.12版本,需要在配置文件里打开debug模式

vi config.yml

... # 如果版本更低的话,配置文件是 config.py 
# Debug = true 
DEBUG: true

实践

打开api文档,以下是不同版本的api文档对应地址

Version Access method example
< 2.0.0 http://<url>/docs http://192.168.244.144/docs
>=2.0.0 http://<url>/api/docs/ http://192.168.244.144/api/docs/
>=2.6.0 http://<url>/api/docs/ http://192.168.244.144/api/docs/

我部署的是2.12版本,因此访问地址是:http://{url}/api/docs/

结合官方提供的架构图和接口文档阅读,我们定位到我们需要改造是koko模块,接下来要做的几个步骤:

打通登录功能

  • 下载

    代码库地址拉取相关release分支代码,我这里拉取的是2.12的版本代码

  • 调试跟踪代码

    jumpserver是一个较为成熟的项目,在阅读源码的时候,如果我们从头开始一行一行的看,难以提高效率,因此,在目标明确的时候,我们可以从api接口切入,倒推其中逻辑,借此逐渐弄清逻辑。

    我们点击web控制台,发现访问的接口是http://{url}/api/v1/perms/users/assets/{uid}/system-users/

    此接口连接后建立起来了一个websocket连接,进行数据交换,有点类似我们前面说的shellhub类似的原理。

  • 编译

    项目根目录下有makefile,我们执行 make linux-amd64即可

  • 发布

    在这里为了调试方便,我直接将koko二进制拷贝到koko的docker镜像中测试

    docker cp koko jms_koko:/opt/koko/
    

    重启镜像即可

    观察日志:

    docker logs -t -f --tail 50  jms_koko
    
  • 重新打镜像。

    docker commit -m "备注" -a "作者" 容器id 镜像tag
    

同步设备数据

调用对应接口传输数据

阅读jumpserver的文档后才发现,仅仅添加设备信息,因为涉及到用户、权限、设备,所以相关api很多,我们可以拷贝到postman,在本地进行调试,并将其封装融入到我们实际项目中。

以下是部分相关接口的postman截图