
简介JumpServer是一款开源的堡垒机系统用于统一管理服务器访问权限并记录操作日志是运维审计和等保合规的重要工具。v2.1.0适合离线或受控网络环境下的私有化部署这份RAR压缩包面向运维工程师、系统管理员及安全入门学习者可解决在线安装易受网络影响、手工配置繁琐等痛点。包内共3个文件包含一个tar.gz源码包、一个sh一键部署脚本及一个md5校验文件整体仅6.19MB携带方便。部署脚本用于自动化初始化和依赖配置md5文件则确保源码包未被篡改。资源已有556人学习下载说明该方案获得一定认可。通过这套资料读者可获得完整源码、校验文件及一键部署脚本快速搭建JumpServer堡垒机实现资产管理、操作审计和权限分配对运维新手也有助于理解部署逻辑与文件组成。1. jump server 不是一台普通跳板机它把 SSH 接入变成一条可控流水线半夜手机响某公司的运维同学爬起来处理线上故障想登录那台内网数据库服务器首先得翻共享文档找口令口令还分散在几个人手里谁也说不清谁能登、谁登过。这种场景下jump server 这类系统就是标准答案把人、资产、授权收口到一个界面所有 SSH 连接都经过它代理操作全程有审计。这份 jump server-v2.1.0 资源包就是一套能直接部署的跳板机方案包含源码、配置模板和初始化脚本适合运维、安全工程师、以及想规范服务器访问的团队。下面我按实际部署顺序拆一遍新手能跟着落地熟手直接看后面几章的参数和踩坑就够。2. 拆 core 设计认证、代理、审计三件事v2.1.0 是怎么组织代码的2.1 为什么你需要一台“代理型”跳板机如果现在只有两三台服务器直接用 ssh 登录问题不大。但服务器一旦超过十台或者团队里有人离职传统直连的毛病就出来了口令散落在个人收藏夹、共享文档甚至聊天记录里有没有人半夜登过机器、执行过什么命令完全没记录权限只能给到“整台机器”没法限制“只能跑这个应用的重启脚本”目标机的 22 端口被迫对所有人开放暴露面太大。jump server 的做法是不再去碰目标机的 22 端口它在中间加一层代理用户先登录跳板机跳板机再拿着资产绑定的系统用户去连目标机。目标机只认跳板机的 IP其他人从外部扫到 22 端口也无所谓因为防火墙可以只放行跳板机。这种“代理型”结构带来的直接好处有三个第一口令不用发给每个人个人拿自己的跳板机账号登录就行第二所有会话都能被录下来出错后可以回放第三离职时只要禁用跳板机账号连目标机的权限也自动收回了。这三点单独拿出来都不算什么合在一起就是运维规范的基础。提示如果你准备在现有网络里加 jump server最好先梳理好“资产”和“系统用户”两个概念。资产就是你要管理的那台服务器系统用户是 jump server 用来登录目标机的账号比如 root 或 deploy。2.2 认证、授权、审计三个模块怎么配合这套 v2.1.0 的代码结构里三个核心模块非常清晰认证模块负责“你是谁”。它支持本地账号、SSH Key也可以对接 LDAP 目录服务。实际部署时我一般先用本地账号跑通再考虑对接统一认证。授权模块负责“你能连哪台”。它维护的是“用户—资产—系统用户”三层映射。也就是说某个用户被授权到某台资产的某个系统用户他登录跳板机后才能发起对应连接。审计模块负责“你干了什么”。它记录登录时间、源 IP、命令列表并且用会话录制的方式把整段 SSH 交互存成可回放的文件。这三个模块在资源包里分别落在 apps/users、apps/assets、apps/audits 三个目录。目录结构大致是jump_server-v2.1.0/ ├── apps/ │ ├── assets/ # 资产、授权规则、系统用户 │ ├── users/ # 用户、用户组、认证 │ ├── audits/ # 登录日志、命令记录、会话录制 │ └── terminal/ # Web 终端、SSH 代理核心 ├── conf/ │ ├── config.py # 数据库、Redis、监听端口 │ └── settings.py # 业务开关、录制参数 ├── requirements.txt # Python 依赖列表 ├── deploy.sh # 一键初始化脚本 └── README.md第一次打开资源包先不要急着跑部署脚本把 conf/config.py 打开看一遍就行。里面会把数据库连接、Redis 地址、监听端口这些最关键的参数集中放好改完再用 deploy.sh会省掉很多来回排查的时间。2.3 技术栈选型为什么是 Python 后端 Web 终端v2.1.0 后端是 PythonWeb 终端是基于 WebSocket 的实时通道配合 Redis 做会话状态缓存MySQL 存业务数据。这个组合在一线运维场景里比较常见原因是 Python 生态里做资产管理、权限校验的现成组件多部署和二次开发的门槛也低。相比纯 Go 或者纯 Node 的实现这个组合更适合团队里有人能看懂、能改。另外Web 终端和 SSH 代理是两套通道。用户在浏览器里打开终端实际是 WebSocket 连到 jump server 的 terminal 服务terminal 服务再通过 SSH 协议连目标机。这个链路里WebSocket 负责浏览器到跳板机这一段SSH 负责跳板机到目标机这一段。中间的数据会被审计模块复制一份用于录制和命令过滤。2.4 关键配置项端口、数据库、会话录制参数部署前先把下面这张表过一遍大多数配置在 conf/config.py 里都能找到对应项。配置项默认值建议说明SSH 代理端口2222生产环境统一改掉用户命令行连跳板机时用的端口Web 监听端口8080用 Nginx 反向代理后改为内网端口浏览器访问的入口MySQL 数据库名jumpserver独立库不要共用字符集必须为 utf8mb4Redis 数据库序号0单独使用一个 db用于会话缓存不要和业务缓存混会话录制目录media/放到 /data 下的大磁盘录制文件增长很快需要容量冗余SECRET_KEY随机串首次部署后改掉用于加密密码和会话密钥参数给到这一步我一般会先把 MySQL 和 Redis 起起来然后再回去改 config.py。否则配置文件改完服务一启动连不上数据库又要回来排查。2.5 与纯 SSH Gateway 的差异日志和命令过滤为什么更重要纯 SSH Gateway 只做转发不解析 SSH 协议内容所以它只能记录“谁在什么时间连了哪台机器”记录不了具体命令。v2.1.0 这类带 Web 终端和不带 Web 终端的代理最大的差别在于Web 终端能拿到明文输入输出可以在协议层做命令过滤和关键字告警。比如你可以配置禁止生产库资产上执行drop database用户在 Web 终端里敲出来会被直接拦截。纯 SSH Gateway 根本做不到这一点这就是我坚持选这套方案的原因。当然Web 终端也有自己的坑比如浏览器兼容性、粘贴大段命令时的性能问题这些后面会有排障说明。2.6 生产部署时组件怎么放单机验证与多机分离最小验证环境可以把 Web、终端、MySQL、Redis 全塞在一台机器上但生产环境我不会这么干。常见做法是拆成三层数据库和 Redis 一组jump server 应用一组再前面挂 Nginx。应用节点可以横向扩展但终端服务需要和 Web 共用 Redis才能让用户在一个节点发起连接、另一个节点也能感知会话。组件分离后配置文件里要改的是数据库和 Redis 的地址不能再写127.0.0.1而要写对应节点的内网 IP。这时候网络策略就很重要数据库和 Redis 不需要暴露公网安全组只允许应用节点访问即可。这些在单机部署阶段都是用不到的但提前知道后面迁移就不会抓瞎。3. 部署一套最小可用的 jump server从解压 rar 到接入第一台 Linux 主机3.1 环境准备版本对齐是第一步v2.1.0 的依赖清单要求 Python 3.6 以上、MySQL 5.7 以上、Redis 3.2 以上。部署前先确认版本免得跑到一半因为组件太新出现兼容性报错python3 --version mysql --version redis-cli info | grep redis_version如果本机没有 MySQL可以先用 Docker 起一个注意指定字符集否则后面中文资产名很容易报错docker run -d \ --name jumpserver-mysql \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDpassw0rd \ -e MYSQL_DATABASEjumpserver \ mysql:5.7 \ --character-set-serverutf8mb4 \ --collation-serverutf8mb4_unicode_ci这里MYSQL_DATABASE直接创建了库character-set-server和collation-server两个参数指定了默认字符集。如果不加这两个参数MySQL 默认的 latin1 会让中文用户名和资产名在入库时变成乱码后面搜索和导出都会出问题。这是我第一次部署时踩过的坑当时所有中文资产在列表里都是???查了半天才发现是建库时没指定字符集。3.2 解压并安装依赖rar 包在 Linux 下解压我习惯用 7z因为 unrar 在最小化安装里经常没有7z x jump_server-v2.1.0.rar -o/opt/jumpserver cd /opt/jumpserver chmod x deploy.sh-o后面的目录如果不存在7z 会创建。解压完成后先给部署脚本加执行权限否则直接./deploy.sh会报权限不足。接下来创建虚拟环境并安装依赖python3 -m venv venv source venv/bin/activate pip install -r requirements.txt用虚拟环境不是为了装样子是避免把依赖装到系统 Python 里污染其他项目。如果服务器在国内网络可以临时把 PyPI 源换成内网镜像源具体地址各家不一样只要保证能拉通依赖就行。装完之后可以用pip check验证依赖冲突网络状况差的时候这一步特别有用。3.3 修改配置数据库、Redis、密钥打开conf/config.py至少要把下面几项改成自己的环境值DB_HOST 127.0.0.1 DB_PORT 3306 DB_NAME jumpserver DB_USER jumpserver DB_PASSWORD your-db-password REDIS_HOST 127.0.0.1 REDIS_PORT 6379 REDIS_DB 0 SECRET_KEY please-change-me-to-a-random-string如果 MySQL 容器已经跑起来了还要在库里创建专用账号CREATE USER jumpserver% IDENTIFIED BY your-db-password; GRANT ALL PRIVILEGES ON jumpserver.* TO jumpserver%; FLUSH PRIVILEGES;这里注意SQL 里的%表示允许任何 IP 连接。如果 MySQL 和 jump server 在同一台机器也可以收紧为localhost。但如果你把 jump server 单独部署MySQL 在另一台机器上一定要给%否则连接时会被 MySQL 拒绝。3.4 初始化数据库并创建管理员依赖装好、配置改好之后执行数据库迁移python manage.py makemigrations python manage.py migrate python manage.py createsuperusermakemigrations会根据模型生成迁移文件migrate把迁移文件应用到数据库。createsuperuser 是交互式的会依次问用户名、邮箱、密码。邮箱可以直接回车跳过用户名和密码别用太弱的因为这是管理后台的入口。如果后续还要写脚本调用 API需要再生成一个 API Token这个可以在 Web 后台的用户详情页里创建也可以直接通过接口申请后面进阶章节会用到。3.5 启动服务并接入第一台主机本地验证阶段可以直接用 Django 自带的 runserver 启动python manage.py runserver 0.0.0.0:80800.0.0.0表示监听所有网卡这样你才能从自己的电脑访问。生产环境不要这么干换成 gunicorn 跑下面只是本地验证gunicorn -w 4 -b 0.0.0.0:8080 jumpserver.wsgi:application服务起来后浏览器访问http://server-ip:8080用刚才创建的管理员登录。添加资产有两种方式界面点击最直接脚本批量导入更快。这里给一个用 API 添加资产的例子# 1. 获取 token TOKEN$(curl -s -X POST http://127.0.0.1:8080/api/token/ \ -d {username:admin,password:admin123} \ | python3 -c import sys, json; print(json.load(sys.stdin)[token])) # 2. 添加一台 SSH 资产 curl -s -X POST http://127.0.0.1:8080/api/assets/assets/ \ -H Authorization: Bearer $TOKEN \ -H Content-Type: application/json \ -d {name:web01,address:192.168.1.10,protocol:ssh,port:22}这段命令先调用登录接口换 token再用 token 请求资产接口。name是资产显示名address是目标机 IPport是目标机 SSH 端口。如果目标机用的不是标准 22 端口改port就行。响应里会出现id字段后面给用户授权时要用。3.6 验证连接命令行 SSH 直连会被代理拦下来添加完资产先别急着在 Web 终端点连接可以先试命令行通道ssh -p 2222 admin127.0.0.1这里的admin是 jump server 里的账号不是目标机的系统用户。jump server 收到连接后会要求你选择要访问的资产然后再用资产绑定的系统用户去连目标机。第一次连接时目标机如果开了 StrictHostKeyChecking可能会提示指纹确认这是正常的。整个过程里目标机看到的连接发起方是 jump server 的 IP不是你的办公网 IP。这也解释了为什么后面排查问题时目标机侧的last结果很少能帮上忙。3.7 给资产绑定系统用户root 直连还是普通用户资产添加完成后还需要给资产绑定一个系统用户否则 jump server 不知道用它去连目标机时该用哪个账号。常见的做法有两种直接绑定 root或者绑定一个有 sudo 权限的应用用户。我一般建议绑定普通用户少用 root这样审计记录里还能看到具体是谁通过 sudo 提权执行的命令。在 Web 界面上系统用户配置里需要填目标机上的真实账号和密码或者选择一个 SSH Key。jump server 会把密钥托管起来连接时自动装载。这里需要注意的是如果目标机禁用了密码登录、只留密钥那系统用户必须绑定密钥。密钥权限要设成 600否则 OpenSSH 会直接拒绝使用。4. 常见问题与排查五处最容易翻车的配置点4.1 现象Web 页面能打开但点“连接”后一直转圈原因Web 终端服务没有启动或者浏览器到跳板机的 WebSocket 通道被 Nginx 截断了。很多人只启动了 Django 的 HTTP 服务忘了 terminal 服务也要跑起来。解决确认两个进程都在跑。如果是用 runserver它其实能同时提供 WebSocket但如果你接入了 Nginx就必须把升级协议的请求转发对location /ws/ { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_read_timeout 3600s; }关键就是Upgrade和Connection两个头少了任何一个WebSocket 握手都会失败。别问我为什么知道我第一套环境就是加了 Nginx 后控制台一直报 400。4.2 现象命令行连 2222 端口提示 Connection refused原因跳板机没有监听 2222 端口或者防火墙没有放行。解决先看监听ss -lntp | grep 2222如果没有任何输出说明 SSH 代理服务没起来检查终端服务的日志。如果监听正常再检查防火墙firewall-cmd --add-port2222/tcp --permanent firewall-cmd --reload注意云服务器还要看安全组规则仅改本机防火墙是没用的。我遇到过在云上把云厂商安全组漏掉的情况本地ss显示监听没问题外部就是连不上翻车翻得很彻底。4.3 现象migrate 时报 Duplicate column name原因数据库里残留了旧版本的表结构或者 migrations 目录里有重复的迁移文件。v2.1.0 和新一点的版本混跑时特别容易出现。解决先备份数据库然后检查迁移状态python manage.py showmigrations找到标着[X]的对应迁移用--fake把它标为已应用python manage.py migrate --fake assets 0001_initial--fake的意思是告诉 Django 这个迁移已经执行过不再实际跑 SQL只更新记录。这招能绕过重复列问题但用不好会掩盖真实的结构差异。我的习惯是先把表结构 diff 出来看一遍确认只是列重复才用 fake否则老实手工修库。4.4 现象会话录制文件是 0 字节回放黑屏原因录制命令执行依赖 ffmpeg录制目录权限不对或者磁盘满了。ffmpeg 如果没装跳板机不会报错只是录像文件写不进内容看起来很像是黑匣子。解决装上 ffmpeg然后确认 media 目录存在且可写yum install -y ffmpeg mkdir -p /data/jumpserver/media chown -R jumpserver:jumpserver /data/jumpserver/media录制文件从产生到可回放中间其实经过了一个临时写入和转码的过程所以刚结束的会话几秒内看不到录像很正常。如果过了几分钟还是 0 字节再去查 ffmpeg 的日志。4.5 现象管理员添加了资产普通用户登录后看不到原因授权规则没覆盖该用户或者用户和资产不在同一个规则节点下。v2.1.0 的授权不是简单的“勾选即生效”它会按节点匹配继承。解决在授权规则里创建一条“用户组→资产组→系统用户”的映射。检查时注意用户登录后默认只能看到规则命中的资产不是所有资产。如果你建的规则只授权了/default/节点下的资产而新资产放在/AWS/节点用户看不到是正常的# 伪代码授权规则的关键匹配逻辑 if user in rule.users and asset in rule.assets and system_user in rule.system_users: return True提示改完授权规则后用户不需要重启服务重新登录或者刷新资产列表即可。如果还是看不到查看用户所属用户组规则是否绑定的是用户组而非单个用户。5. 进阶技巧批量导入资产与连接自测脚本5.1 用 API 批量导入资产如果手上有一百台机器Web 界面点起来太慢。我一般从 CMDB 导出一份 CSV然后用脚本批量调 API。先看 CSV 格式name,address,protocol,port,node web01,192.168.1.10,ssh,22,/default/ web02,192.168.1.11,ssh,22,/default/然后跑这个 Python 脚本import csv import os import requests API_BASE http://127.0.0.1:8080/api TOKEN os.getenv(JS_TOKEN) headers {Authorization: fBearer {TOKEN}} with open(assets.csv) as f: for row in csv.DictReader(f): r requests.post(f{API_BASE}/assets/assets/, headersheaders, jsonrow) if r.status_code ! 201: print(ffailed: {row[name]} - {r.text})脚本核心是遍历 CSV 的每一行POST 到资产接口。注意 token 不要写在代码里用环境变量JS_TOKEN传入避免文件被上传到 git 仓库泄密。5.2 连接自测脚本部署完成后我最少会跑一遍这样的自测确保 2222 端口通、代理能转发for ip in web01 web02; do nc -zv $ip 2222 echo $ip ok || echo $ip fail done但nc只能测端口通不通测不了认证链路。所以我还会在脚本里额外调一次 WebSocket 的握手接口确认终端服务在线。自从有一次因为忘记启动终端服务导致整个环境“看起来正常、实际连不上”之后我每次部署完都强制走一遍连接自测把这个脚本放到部署文档的最后一步已经成了固定习惯。希望帮到你。本文还有配套的精品资源点击获取