一、背景
我们开发的一个运维平台需要使用到Webshell功能,用户能够ssh登录到目标主机。正好我们也在使用jumpserver作为堡垒机,才符合运维审计规范要求。并且经过多个web terminal的项目调研,最终是把jumpserver堡垒机的Web terminal集成进来。
方案很简单,就是把Jumpserver的web terminal的页面通过iframe的方式集成到我们运维平台界面即可。但是我们的站点和jumpserver怎么集成呢?
jumpserver本身有自己的cookie认证机制,要把两者打通,想到的方法就是通过nginx反向代理一个location 例如 /jms 代理到整个jumpserver服务,并且我们也在这个nginx反向代理自己的运维平台服务。 运维平台服务提供一个登录接口,这个接口内部调用jumpserver的认证接口,拿到session_id的cookie, 最后把这个cookie发送到客户端,客户端进行存储。
等下次用户登录服务器,后台把这个过程操作一遍,访问iframe嵌套的jumpserver web terminal页面就能正常进入(cookie会自动带过去,经过了认证,页面不会被跳转到jumpserver的登录界面了)资产清单页面,用户选择资产进行登录即可。
二、jumpserver使用nginx进行二级代理配置
查看了官方文档,说可以实现nginx二级代理,但是直接使用里面的例子,还是有问题。
官网原文链接: https://docs.jumpserver.org/zh/v4/installation/proxy/?h=%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86#3-slb 
好像很简单对吧,配置nginx的location /jms即可。但是理想很丰满,现实很骨感。 这里提供的配置文件,替换的url不全,导致前端界面跳转存在问题。
自己根据实现原理,做了一版本实际测试,修改了有问题的URL替换,最终满足了我的需求.
三、实现原理
原文的nginx配置内容如下:

四、改良后的nginx二级配置内容
html
location /jms {
# 替换成自己实际jumpserver的后端
proxy_pass http://192.168.2.211:30081;
rewrite "/jms/(.*)$" /$1 break;
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect ~^/(.*) http://$http_host/jms/$1;
# 针对响应给客户端的内容,进行字符串替换,将css、js、接口响应内容如静态资源的url前缀修改
# 让前端页面的资源请求、接口请求,都通过添加/jms/前缀URL进入这个location,进行反向代理
sub_filter_types *;
sub_filter_once off;
sub_filter_last_modified on;
sub_filter '/koko/static/plugins/elfinder/i18n' '/jms/koko/static/plugins/elfinder/i18n';
sub_filter '/koko/static/js/jquery-ui-1.12.1.js' '/jms/koko/static/js/jquery-ui-1.12.1.js';
sub_filter '/koko/static/js/jquery-3.3.1.js' '/jms/koko/static/js/jquery-3.3.1.js';
sub_filter '/koko/static/plugins/elfinder/css/theme-jms.css' '/jms/koko/static/plugins/elfinder/css/theme-jms.css';
sub_filter '/koko/static/plugins/elfinder/css/elfinder.full.css' '/jms/koko/static/plugins/elfinder/css/elfinder.full.css';
sub_filter '/koko/static/js/jquery-ui-1.12.1.min.css' '/jms/koko/static/js/jquery-ui-1.12.1.min.css';
sub_filter '/koko/static/plugins/elfinder/elfinder.full.js' '/jms/koko/static/plugins/elfinder/elfinder.full.js';
sub_filter '/koko/static/plugins/elfinder/i18n/elfinder.pl.js' '/jms/koko/static/plugins/elfinder/i18n/elfinder.pl.js';
sub_filter '/koko/static/js/koko.js' '/jms/koko/static/js/koko.js';
sub_filter '/koko' '/jms/koko';
sub_filter '/api/v1/settings/i18n/luna/' '/jms/api/v1/settings/i18n/luna/';
sub_filter '/api/v1/settings/i18n/koko/' '/jms/api/v1/settings/i18n/koko/';
sub_filter '/static/' '/jms\/static/';
sub_filter '/ui/' '/jms/ui/';
sub_filter '"ui/' '"jms/ui/';
sub_filter "'ui/" "'jms/ui/";
sub_filter '/api/' '/jms/api/';
sub_filter '/core/' '/jms/core/';
sub_filter '/ws/notifications/' '/jms/ws/notifications/';
sub_filter '/ws/ops/tasks/log/' '/jms/ws/ops/tasks/log/';
sub_filter '/luna/' '/jms/luna/';
sub_filter '/koko/' '/jms/koko/';
sub_filter '/koko/connect' '/jms/koko/connect';
sub_filter '/lion' '/jms/lion';
sub_filter '/media/' '/jms/media/';
sub_filter '/omnidb/' '/jms/omnidb/';
}
五、最终测试结果如下,正常使用


