☰
JumpServer堡垒机容器化部署:从选型到审计闭环
2026/10/1 11:27:28 网站建设 项目流程

运维干得越久,越明白一个道理:服务器安全的最大漏洞往往不是漏洞本身,而是“人”这个环节。团队几个人共用一台机器的 root 口令,离职员工的资产权限迟迟没有清,半夜有人登进生产库改了个配置,事后连登录时间线都拉不出来——这些场景我相信绝大多数运维都经历过。要治这类问题,常规的做法就是上堡垒机。JumpServer 是目前开源圈子里活跃度最高、社区生态最完整的堡垒机系统,本质上是给所有运维人员套上一道“门禁 + 监控”,把身份认证、账号纳管、权限授权、操作审计全部接到统一入口里。这篇文章我会完整走一遍 JumpServer 的容器化部署流程,从方案选型、环境初始化、一键安装,到资产纳管、权限策略、会话审计,再到生产环境必须做的 HTTPS、备份与升级,最后把这几年部署 JumpServer 踩过的坑一并整理出来。适合第一次搭堡垒机的运维团队,也适合希望系统理解 JumpServer 整体架构的进阶读者。

1. 部署前的需求分析与方案选型

1.1 功能定位:为什么跳板机解决不了问题

先讲一个我见过的典型反面案例。某团队为了管理十几台服务器,直接拿一台内网机器当跳板机,所有人的公钥都塞进 authorized_keys,然后日常就在 root 上操作。好处是省事,坏处是全乱:谁密钥过期了没人知道,谁在什么时间登过机说不清楚,更别提操作录像和命令审计。一旦出现数据被误删或者被恶意篡改的事故,连最基本的“谁干的”都定位不了。

堡垒机解决的其实是三个维度的问题:身份统一、权限收敛、行为可溯。JumpServer 在这三个维度上都做到了产品化,和自维护跳板机完全是两种工作方式。它的用户模型不是“IP + 端口”,而是“账号 + 授权”。运维人员只需要记住 JumpServer 的地址和密码,登录后看到的是被授权的资产,连接目标主机时系统自动完成账号映射,所有操作都会被录下来。这样既不用大规模分发 SSH 密钥,也可以随时通过授权策略动态调整某个人的访问范围,不用逐个去登录目标机器改配置。

运维安全里有一个概念叫“最小权限原则”,堡垒机是落地这一原则最方便的抓手。你可以在 JumpServer 里把同一个资产的访问权限分成“只读运维”和“完整运维”两档,甚至细分到命令黑白名单层面。这个粒度是普通跳板机完全做不到的,也是等保合规里安全审计、访问控制部分非常看重的功能。

1.2 部署方式对比:容器化、离线包还是源码

JumpServer 官方提供的部署路径主要有三条:Docker Compose 在线脚本部署、离线安装包部署、源码手动部署。我给一个比较直观的对比表:

部署方式推荐场景优点主要坑点
Docker Compose 在线脚本大多数中小团队、功能评测、POC 验证几分钟能跑起来,组件依赖少,官方升级支持好首次拉取镜像耗时,依赖网络环境
离线安装包内网隔离环境、等保交付、无外网机房不依赖外部仓库,可复制性强版本可能滞后,升级需要重新准备包
源码部署二次开发、深度定制组件拆分清楚,可以改代码组件数量多,部署周期长,日常维护成本高

我自己的建议很明确:没有强定制需求,就不要碰源码部署。JumpServer 的容器化方案已经把 MySQL、Redis、Core、Koko、Nginx 等组件全部编排好,生产环境用官方 installer 做部署和维护升级是最省心的路径。后面我以 v3.x 版本的容器化部署为主线展开,同时把离线包方式的使用要点也捎带说明。

1.3 资源规划:别让跳板机成为性能瓶颈

JumpServer 的资源需求容易被低估。官方建议最低 2核4G,但实际部署经验证明,这个配置只适合十台以内资产的轻量使用。一旦并发 Web Terminal 连接超过二十个,再加上定期资产改密、会话录像转存这类任务,CPU 和内存很容易顶到 90% 以上。我的生产环境建议是至少 4核8G,磁盘按 100G 起步,并保留后续扩容空间。

磁盘是最容易被忽略的一块。堡垒机的数据会持续增长,大头是会话录像、操作日志和数据库 binlog。以我的经验,一个中等规模的运维团队,如果开了录像审计,每天新增数据量可以到 1 到 2GB,录像保留 90 天的话,200G 磁盘都不算宽裕。建议部署时直接挂独立数据盘,不要把系统盘和数据目录混在一起。

网络规划方面,JumpServer 对外只需要暴露 Web 端口,默认 80/443。如果运维团队习惯用 SSH 客户端直连,再放行 Koko 的 2222 端口。MySQL 和 Redis 属于内部组件,不应该映射到宿主机公网。下面是端口职责简表:

组件默认端口用途
Nginx80 / 443Web 访问入口
Koko2222SSH 直连入口(可关闭)
Core8080内部 API 服务
MySQL容器内 3306持久化
Redis容器内 6379缓存与消息

注意:内部组件的端口不建议直接暴露到公网,堡垒机对外只留 80/443 是安全性最高、维护成本最低的姿势。生产环境登录建议强制加 MFA 口令,后面我会在初始化部分展开。

2. 环境初始化:部署前必须做好的基础动作

2.1 时间同步、SELinux 与防火墙

很多 JumpServer 的部署问题其实出在环境本身,而不是 JumpServer 上。第一个要做的就是时间同步。堡垒机是强审计系统,所有会话记录、命令记录、工单审批都依赖准确的时间戳。如果服务器时间和客户端时间相差太大,登录时会直接报“时间偏差过大”,审计时间线也会乱。部署前务必将时区设置为 Asia/Shanghai,并配置 NTP 同步。实践做法是先手动同步一次,再写入 cron 每分钟或用 chrony 保持持续同步。

第二步处理 SELinux。CentOS 上默认开启的 SELinux 会影响 Docker 容器的网络和文件权限,尤其容易出现容器内 Nginx 无法读写证书目录这类问题。我习惯直接设为 disabled:

setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

第三步是防火墙。安装阶段为了减少干扰变量,可以先把 firewalld 停掉,等整体跑通之后再按端口清单逐项放行。放行规则建议单独做,不要用 docker 的 iptables 和系统的 firewalld 互相打架。生产环境的放行顺序是:先放行 80/443,再根据实际情况放行 2222,其他端口一律不放。

2.2 Docker 环境准备与镜像加速思考

JumpServer 的容器化部署依赖 Docker 和 Docker Compose。官方 quick_start 脚本会在检测到环境缺失时自动帮你安装 Docker,但为了脚本执行更顺畅,我建议手动装好。以 CentOS 7 为例,用阿里云镜像源安装 Docker CE,把 Docker 设为开机自启。Compose 插件版本也很关键,v2 之后的 Docker 里自带 docker compose 子命令,如果安装的是旧版 docker-compose 二进制,记得确认版本在 2.20 以上。

镜像拉取速度是第一次部署最容易卡住的环节。JumpServer 的镜像托管在 Docker Hub 和 GitHub Packages,国内网络直连偶尔很慢。一个务实的做法是在安装前先配置镜像加速地址,在 /etc/docker/daemon.json 中写入可用的 registry-mirrors 配置,重启 Docker 后再执行部署脚本。具体的镜像地址要以当前网络环境下实测可用为准,不同区域差异比较大。

2.3 安装目录与部署放行的检查清单

整理一份安装前逐项确认的清单,可以节省大量排障时间:

  • 时区已经改为 Asia/Shanghai,NTP 同步正常
  • SELinux 已 disabled,或至少处于 permissive 模式
  • 防火墙与云安全组已放行 80/443
  • Docker 已启动,docker compose 版本正常
  • 磁盘剩余空间至少 50G,且目标安装目录可写
  • 能正常访问下载站点(或已准备好离线安装包)

确认完这些再动脚本,部署失败的概率会低非常多。我在实际项目中见过太多因为环境没准备就执行脚本,最后绕了一大圈才发现是基础环境问题的案例。

3. 一键部署实操全记录:从脚本到容器跑起来

3.1 执行 quick_start.sh,脚本里到底做了什么

v3.x 版本官方推荐通过一键安装脚本快速部署。从下载源获取 quick_start.sh 后,直接交给 bash 执行。脚本运行期间会先做环境检查,然后询问几个关键参数:安装目录默认 /opt/jumpserver,Web 访问端口默认 80,还会生成随机的数据库密码和加密密钥。整个过程大约十分钟,取决于镜像拉取速度。

需要特别提醒的是:脚本执行中尽量不要用 Ctrl+C 中断。官方脚本会自动判断是否已经初始化过,如果中途中断,容易留下半初始化状态,再次执行时逻辑判断会变得比较绕。执行完成后脚本会输出安装目录、访问地址和管理员账号。这段输出信息一定要保存好,后续初始化配置经常要回查。

3.2 看懂容器编排与配置文件

安装完成后进入 /opt/jumpserver-installer-v3.x.x 目录,可以看到 docker-compose.yml、.env、config 等文件。核心配置以环境变量形式存放在 config 目录里。整个体系由一组命名规范的容器组成:jms_core、jms_koko、jms_web、jms_nginx、jms_mysql、jms_redis、jms_celery、jms_beat。每个容器职责单一,排障时可以按报错组件直接进容器看日志。

这里我把组件和职责理一遍,方便后续排障时快速定位:

容器职责常见故障关联
jms_coreDjango API、认证、审计核心登录失败、接口 500
jms_kokoWeb 终端、SSH 代理连资产超时、WebSocket 断连
jms_web前端静态页面页面白屏、静态资源 404
jms_nginx统一入口、HTTPS证书问题、端口占用
jms_mysql数据持久化连接数满、SQL 错误
jms_redis缓存、Session、队列登录态丢失、任务堆积
jms_celery异步任务改密失败、工单不推送
jms_beat定时任务调度资产扫描不执行

运维上有一个很实用的思路:遇到 JumpServer 功能异常,先看 jms_core 日志,因为绝大多数业务逻辑都走 core 接口;再看对应组件日志定位。比如改密失败大概率有 celery 的日志线索,连接资产失败直接看 koko 日志。

3.3 启动服务、健康检查与首次访问

installer 目录下提供了 jmsctl.sh 管理脚本,日常启停用 ./jmsctl.sh start 和 ./jmsctl.sh stop。部署完成后先确认所有容器处于 healthy 状态:

cd /opt/jumpserver-installer-v3.x.x ./jmsctl.sh status docker ps | grep jms

首次访问直接用浏览器打开 http://服务器IP。此时会进入初始设置页面,需要设置管理员账号和密码。注意不要把这个账号和资产系统用户混为一谈,它就是 JumpServer 平台本身的超级管理员。初始化完成后,登录后台第一件事去“系统设置”里把默认安全策略改掉,包括开启登录失败锁定、设置密码复杂度、开启 MFA。我见过太多部署完就晾在那里的团队,管理员密码还是初始的简单口令,这台堡垒机反而成了新的风险点。

3.4 补充:离线安装包部署流程要点

在无法访问外网的场景下,离线包是更现实的选择。流程是先在一台有外网的机器上下载特定版本的 jumpserver-installer 压缩包,随包带上所需镜像 tar 文件,传输到目标服务器。解压后执行安装脚本,脚本会使用本地镜像导入,不依赖远程仓库,整体安装速度和在线方式接近,只是包体比较大,一般在几百 MB 到 2G 不等。离线方式最大的价值在于交付的可复现性,尤其适合等保验收前一次性交付多个环境。

离线包部署的注意事项和在线方式基本一致,唯一的差别是多了一个“镜像导入”的环节。导入完成后用 docker images 检查镜像列表是否完整,再执行启动命令。如果镜像不完整,后续容器会反复重启,且日志里报的错误五花八门,很容易让人误判成别的问题。

4. 业务落地:初始化平台、纳管资产、授权与审计闭环

4.1 第一次登录后的安全初始化动作

创建完管理员账号后,建议按这个顺序做初始化:

  1. 修改管理员密码,绑定手机号并开启 MFA。
  2. 在系统设置里配置 SMTP 邮件通知,这里的收件人验证是后续工单审批、密码过期提醒能跑起来的前提。
  3. 关掉不必要的注册接口和默认开放端口。
  4. 按部门或团队创建组织结构和用户组,不要每个人都给管理员角色。
  5. 设置会话审计存储与录像保留策略,明确录像保留天数。

每次给新团队做 JumpServer 交付,我都会先把这几步做完再纳资产。原因很简单:堡垒机是安全入口,入口本身的安全性如果没挡住,后面对接多少资产管理模块都是白搭。MFA 尤其关键,它能把密码泄露的风险降低一个量级。

4.2 资产纳管:搞懂资产、系统用户、授权策略三个概念

JumpServer 使用起来最需要理解的是三张核心表:资产、系统用户、授权策略。

资产的创建非常直观,资产管理 - 资产列表 - 创建,填写 IP、端口、协议即可。系统用户则是目标主机上的真实账号,比如要管理一台 CentOS,需要在系统用户里定义一个 root 或具备 sudo 权限的账号。授权策略是连接器,把哪个用户(用户组)、可以访问哪个资产、用哪个系统用户,三者绑定起来。策略还可以细分登录时间段、命令过滤规则。

我建议在系统用户里使用“特权用户”来做资产测试连接和密码推送,特权用户的周期改密功能可以用来定期轮换资产密码。但要注意,特权用户能不用 root 就不用 root,用带 sudo 的管理账号更安全。系统用户和平台用户是两个完全不同的体系,这个关系想明白,JumpServer 的权限模型基本就通了。为了帮助理解,可以把它类比成“小区大门门禁卡”和“单元门钥匙”:平台用户是门禁卡,控制谁可以进小区;系统用户是单元门钥匙,决定进了小区能打开哪扇门。

批量纳管时使用 CSV 导入非常高效。JumpServer 支持从资产列表页下载模板,核心字段包括主机名、IP、协议、端口、节点路径、系统用户等。需要特别注意 CSV 的编码格式,用 Excel 编辑后保存时务必选 UTF-8 编码,否则中文名称和注释字段在导入时会乱码。一次导入几十台资产的效率提升非常明显,但前提是模板和字段格式必须和官方模板保持完全一致。

4.3 实测 Web Terminal 连接与会话审计回放

资产配好之后,授权策略没有应用前,用户即使能看到资产列表也无法连接。创建策略时优先用用户组 + 资产组维度,而不是单个用户挂单个资产。配置完成后,在资产详情页点“测试连接”,确认链路是通的。

连接测试通过后,从 Web Terminal 发起会话,你会在实时监控里看到会话通道,关闭会话后可以在“会话审计 - 会话记录”里找到本次连接的回放录像、命令记录和文件传输记录。我接触的不少企业客户在验收环节只测试到“能连上”这一步,忽略了审计回放,实际上审计能力才是堡垒机最值钱的部分。这里要实际做一轮“连过去执行几条命令再退出”的验证,确认录像能播放、命令记录能检索,才算真正闭环。

5. 生产加固:HTTPS、备份、升级与第三方联动

5.1 HTTPS 证书配置与 Nginx 对接

Web 端口跑明文 HTTP 在堡垒机场景里非常危险,运维人员的操作口令和令牌如果以明文在网络里传输,路上被看一眼就全完了。生产环境必须启用 HTTPS。JumpServer 官方 Nginx 已预留证书目录,把签名证书放到 /opt/jumpserver/config/nginx/cert/,命名为 server.crt 和 server.key,重启 jms_nginx 即可生效。如果用的是外部证书链,记得把中间证书一并合并到 server.crt 里,否则部分浏览器会报证书链不完整。

如果是用集团统一的 Nginx 网关代理到 JumpServer,需要在外部 Nginx 的 server 块里配置 SSL 终止,并正确转发 WebSocket 升级请求头和客户端 IP 头。这里的核心是 WebSocket 相关配置,如果 Web Terminal 能打开但连接不上目标资产,优先怀疑就是这一层没有配置。把 Upgrade 和 Connection 请求头正确转发后,问题基本都能解除。

5.2 数据库备份、升级与回滚的完整策略

JumpServer 的备份重点在数据库,业务数据都在 MySQL 里。官方 installer 提供了 backup_db 命令:

cd /opt/jumpserver-installer-v3.x.x ./jmsctl.sh backup_db

备份文件会生成到指定目录,建议再配合系统层定时编排,每天凌晨把 database 备份文件和 config 目录同步到独立存储。恢复时使用 restore 相关命令。这里有个经验:升级前一定要在维护窗口备份,升级后先跑一轮核心功能冒烟——登录、连接、打开录像回放,三个都通过才算升级成功。

升级命令是 ./jmsctl.sh upgrade,脚本会自动拉取新的镜像并重启容器。遇到版本跨度较大的情况,先看官方 Release 页面确认数据库迁移要求,不建议跳多个大版本一次升级。如果升级后出现异常,第一时间把备份文件恢复回去,宁可回到旧版本,也不能让堡垒机一直处于半健康状态。

5.3 组织架构、LDAP 对接与监控联动

当团队扩充到上百人时,手动在 JumpServer 里逐个建账号就太痛苦了。JumpServer 支持对接 LDAP/AD,登录页可以切换企业登录模式。对接配置时需要提供 Server URI、Base DN、用户查询字段,并选择用户同步策略。实际操作中我吃过不少亏,比如 Base DN 写错导致用户同步为零,或者 LDAPS 证书未导入导致绑定失败。建议先在测试环境验证一条完整链路:AD 用户能登录、能被同步到 JumpServer 用户组、同步下来的账号能正常收到授权策略。

监控联动也是一个常见需求。企业里有 Zabbix 的话,JumpServer 可以配合 Zabbix 做资产采集,或者反过来,把 Zabbix 自身的访问入口也收敛到堡垒机里统一审计。另外,生产环境中很多团队还会把 JumpServer 的通知对接企业微信、钉钉、飞书,这样工单审批、密码到期、登录异常能直接推到群或个人。做法是在系统设置里选择通知渠道,填入 webhook 地址,核心是测试消息能真实送达。

6. 常见问题与排查技巧实录

6.1 登录、连接、WebSocket 三类高频问题根因

我处理的 JumpServer 故障里,至少一半集中在三个场景:登录失败、资产连接失败、Web 终端断连。

登录失败的常见原因按优先级排查:服务器时间与客户端时间偏差过大;Cookie 缓存了旧会话;core 容器没有启动完成或 API 挂了。先说时间问题,同样一套环境在虚拟化克隆后特别容易出现,因为克隆出来的机器时间和真实时间差了几个月。连接失败则优先看目标资产自身是否可达,很多情况下根本不是堡垒机的问题,而是目标机的防火墙或 SSH 服务没有起来。排查时从 JumpServer 容器内直接 telnet 目标 IP 端口,能快速定位是网络层问题还是应用层问题。

Web Terminal 断连是最隐蔽的一类。如果连接能建立,但过一会就掉线,十有八九是 WebSocket 代理超时配置问题。我之前遇到的一个案例,外部 Nginx 缺了 proxy_read_timeout 配置,导致 60 秒没有键盘输入就自动断开。解决方法是把 proxy_read_timeout 调到 3600 秒,并发数按在线会话数合理上调。

整理一份高频问题速查表:

现象常见根因处理动作
登录一直转圈Redis Session 异常、Core 未就绪、时间不同步检查时间、清缓存、重启 core/redis
页面白屏Web 容器静态资源损坏、Nginx 路由错误看 jms_web 日志,重载 nginx
资产连接超时目标机防火墙、SSH 未启动、Koko 路由不通从 koko 容器内 telnet 验证
Web Terminal 秒断WebSocket 代理超时配置过短调大 proxy_read_timeout
改密任务失败特权用户权限不足、密码不匹配核对系统用户账号并手动测试连接
容器反复重启磁盘写满、OOM、配置连接错误查 resources、dmesg、容器日志

6.2 容器状态异常与存储问题的排查套路

容器反复重启是部署后最常见的异常。遇到这种情况,先不要急着重启整个栈,而是单独看报错容器的日志:

docker logs --tail 200 jms_core

常见根因有三类:磁盘写满导致 MySQL 无法落盘;配置里数据库密码和实际不一致;内存不足触发了 OOM。磁盘写满时 docker 日志里的特征非常明显,通常是 no space left on device。处理方式比较直接:清理容器日志、排查录像目录所在数据盘空间、给 MySQL 的临时目录留出足够余量。内存不足时看 dmesg 里有没有 OOM killer 日志,有的话就需要扩容内存或者调整 docker 内存限制。

排障时我有个习惯:始终从底层往外排查。先看宿主机资源,再看容器健康状态,最后才进应用日志。跳过宿主机直接看应用日志,往往会在错误的方向上浪费很多时间。

6.3 我踩过的几个坑和最终建议

最后分享几个印象深刻的案例。一个客户机房断电后重启整条链路,发现 Web 页面能开但登录一直转圈,查了一圈是 Redis 数据没了导致 Session 校验异常,清理浏览器缓存后恢复正常。另一个是批量资产纳管时,我没先测试系统用户的账号权限,直接授权上线,结果一段时间后资产改密任务全部失败,日志里全是权限不足。从那以后我严格执行“先测试连接,再授权,再启改密”的顺序。

建议第一次搭建时,不要着急把几百台资产一次性塞进去,先用三五台真实重资产验证整个链路。等授权、审计、备份、改密这些动作都稳定了,再批量导入。这种循序渐进的方式能大大降低后续运维的返工成本。

我个人在实际操作中最深的体会是:堡垒机部署的难点不在安装脚本本身,而在权限模型和日常维护策略的持续建设。JumpServer 装起来只是一个 Docker Compose 的问题,但要让团队所有人按规范走工单、走授权、定期检查录像回放,才是真正考验运维管理能力的地方。最后一个建议:把管理员账号和数据库备份策略写进排班文档,同时做一次恢复演练。堡垒机的可用性直接决定了全公司运维入口的可用性,平时不演练,真到故障时才会发现备份也是坏的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询