Jumpserver 是一款由python編寫開源的跳板機(堡壘機)系統(tǒng),實現(xiàn)了跳板機應有的功能?;趕sh協(xié)議來管理,客戶端無需安裝agent。完全開源,GPL授權
設計思路
設計一個跳轉網(wǎng)關,所有登錄操作都從網(wǎng)關通過
網(wǎng)關具有模擬終端的功能,透明的中轉ssh命令,以支持Tab,Ctrl+A,Ctrl-E等快捷鍵,網(wǎng)關既可以記錄操作日志,又可以審計操作命令。設計一個認證模塊
為了實現(xiàn)認證功能,需要有個認證模塊,認證信息存到數(shù)據(jù)庫,用戶使用跳板機首先需要認證。設計一個授權框架
授權是跳板機不可缺少的部分,授權就是用戶和資產的關系,將關系保存的數(shù)據(jù)庫,用戶登錄主機需要先查授權。設計審計模塊
審計是為了追蹤,我們支持了在線監(jiān)控,命令統(tǒng)計,錄像回放功能,供管理員審查。用戶和主機模塊
跳板機脫離不了用戶和主機,所以這兩個部分是基本的模塊,另外我們將主機模塊擴展,實現(xiàn)基本CMDB功能。Web Terminal
現(xiàn)在都流行Web操作一切,于是我們又實現(xiàn)了Web Terminal,供用戶直接在線鏈接服務器,這里實現(xiàn)是用了Tornado來完成的,Tornado實現(xiàn)WebSocket特別簡單。
架構圖

組件說明
Jumpserver 為管理后臺, 管理員可以通過 Web 頁面進行資產管理、用戶管理、資產授權等操作, 用戶可以通過 Web 頁面進行資產登錄, 文件管理等操作是核心組件(Core), 使用 Django Class Based View 風格開發(fā),支持 Restful API
Luna 為 Web Terminal Server 前端頁面, 用戶使用 Web Terminal 方式登錄所需要的組件 ( WebTerminalView )
該組件由團隊自己通過Angular 實現(xiàn),Jumpserver 只提供 API,不再負責后臺渲染html等。-
Koko(CoCo) 為 SSH Server 和 Web Terminal Server 。用戶可以使用自己的賬戶通過 SSH 或者 Web Terminal 訪問 SSH 協(xié)議和 Telnet 協(xié)議資產。KoKo(最新版)是go版本的coco,新的Jumpserver ssh/ws server, 重構了 coco 的 SSH/SFTP 服務和 Web Terminal 服務 ( WebSFTPView )
SSH/SFTP/web terminal/web文件管理 ( WebSFTPView )
實現(xiàn)了 SSH Server 和 Web Terminal Server 的組件,提供 SSH 和 WebSocket 接口, 使用 Paramiko 和 Flask 開發(fā) Guacamole 為 RDP 協(xié)議和 VNC 協(xié)議資產組件, 用戶可以通過 Web Terminal 來連接 RDP 協(xié)議和 VNC 協(xié)議資產 (暫時只能通過 Web Terminal 來訪問)
Guacamole Apache 跳板機項目,Jumpserver 使用其組件實現(xiàn) RDP 功能,Jumpserver 并沒有修改其代碼而是添加了額外的插件,支持 Jumpserver 調用。-
Jumpserver-Python-SDK
Jumpserver Python SDK,(KoKo)Coco 目前使用該 SDK 與 Jumpserver API 交互。為 Jumpserver ssh terminal 和 web terminal封裝了一個sdk, 完成和Jumpserver 交互的一些功能
- Service 通用RestApi 接口類
- AppService 增加了app注冊等
- UserService 用戶使用該類
jms-storage-sdk
主要作為錄像存儲的工具類,支持本地或其他cloud存儲(e.g. oss)
端口說明
Jumpserver 默認端口為 8080/tcp 配置文件 jumpserver/config.yml
KoKo(Coco) 默認 SSH 端口為 2222/tcp, 默認 Web Terminal 端口為 5000/tcp 配置文件在 KoKo(CoCo)/config.yml
Guacamole 默認端口為 8081/tcp, 配置文件 /config/tomcat9/conf/server.xml
Nginx 默認端口為 80/tcp
Redis 默認端口為 6379/tcp
Mysql 默認端口為 3306/tcp

技術實現(xiàn)
使用技術
- Python 3.6.1
- Django
- Angular (Luna)
- go (koko)
- Celery http://www.celeryproject.org/
- Redis cache 和 celery broke
- Flower - Celery monitoring tool
- Guacamole (webterminal -RDP)
- websoket 框架 (https://github.com/kataras/neffos)
服務啟動
./jms start 命令將會下面服務

gunicorn - unix系統(tǒng)的wsgi http服務器,負責jsm-core的http請求
Daphne - 支持HTTP, HTTP2 和 WebSocket 的asgi的服務器,主要處理WebSocket請求
celery - 后臺異步任務分發(fā)處理 -celery_ansible/celery_default
簡單、靈活且可靠的,處理大量消息的分布式系統(tǒng);專注于實時處理的異步任務隊列,同時也支持任務調度flower - 負責監(jiān)控 celery worker執(zhí)行情況
Web Terminal
- 主要通過Luna,koko 和Guacamole實現(xiàn)
Luna
打開web terminal link 后,進入luna, luna 會通過api請求jms 的資源列表,進行樹狀展示
當需要進行RDP訪問時,會向guacamole進行post請求
/guacamole/api/session/ext/jumpserver/asset/add使用 mstsc.js 實現(xiàn)web版的javascript RDP client -https://github.com/citronneur/mstsc.js (很老的框架)
使用 socket.io 和畫布來綁定 mstsc.js 后端。 前端通過 rle.js 文件完成位圖的解壓縮webterminal 前端由luna 里的html5 canvas 和js 渲染出來
-
Luna 使用了 "guacamole-common-js": "1.1.0", 提供了 Guacamole client的實現(xiàn)
http://guacamole.apache.org/doc/guacamole-common-js/<div class="window" [ngClass]="{'active':view.active}" style="height: 100%"> <elements-ssh-term [view]="view" [host]="view.host" [sysUser]="view.user" *ngIf="view.type=='ssh'" > </elements-ssh-term> <elements-guacamole [view]="view" [host]="view.host" [sysUser]="view.user" [remoteAppId]="view.remoteApp" *ngIf="view.type=='rdp'" > </elements-guacamole> <app-sftp *ngIf="view.type=='sftp'" [host]="view.host"></app-sftp> </div>
koko(ssh)
老版本coco使用ssh python 庫- Paramiko
koko 啟動時候會注冊到jms, 需要配置中 “BOOTSTRAP_TOKEN” 與jump server保持一致, 用于身份認證
啟動之后將會監(jiān)聽,當有新的ssh terminal窗口打開,就會嘗通過websocket 建立ssh 連接 (依賴于Daphne),基于go的websocket實現(xiàn)
用戶在web terminal 窗口操作時,koko 會對命令解析,和jms里的過濾規(guī)則匹配
連接中斷后,開始上傳錄像(其實是json文件,記錄了時序log)到jumpserver(/data/media)
-
使用了websoket 框架 - https://github.com/kataras/neffos
20200527094248561_866134588.png
Guacamole(rdp)
- 對Apache Guacamole 進行了改造,主要是Guacamole client/server war包,看不到源碼改造
- 原生的Guacamole 本身可以單獨提供 web terminal 服務,但是部署相對復雜,有單獨的postgresql存儲機器連接信息
- 改造后的Guacamole (),也需要通過 BOOTSTRAP_TOKEN 注冊到 jms
操作錄像回放
操作的錄制: ssh 是由koko基于websocket data完成; rdp 是由Guacamole API 完成
-
操作的回放:由 luna進行 replay 展示的,對ssh 錄像(.json) 進行分割處理,使用js渲染成動畫;
<elements-replay-json [replay]="replay" *ngIf="replay.type=='json'"></elements-replay-json> <elements-replay-guacamole [replay]="replay" *ngIf="replay.type=='guacamole'"></elements-replay-guacamole>
