JumpServer部署实战:三步从零搭建开源堡垒机并接入第一批资产
凌晨两点,运维群里炸了锅。一台生产数据库被误操作,DBA 查看登录记录,发现 root 密码早在三个月前就被前任同事贴进了公开文档,谁登过、改过什么、删了什么,全部无从追溯。这不是个例——服务器密码散落在 Excel、聊天记录、便利贴上,是绝大多数中小团队的真实写照。
如果你也面临同样的问题,本文介绍的 JumpServer 部署方案就是为你准备的。JumpServer 是一款开源的 PAM(特权访问管理)平台,业界通常称之为"堡垒机",它把 SSH、RDP、Kubernetes、数据库和 RemoteApp 等入口统一收敛到浏览器里,让每一次登录、每一条命令、每一次改密都可审计、可控制。读完本文,你将掌握从裸机安装、接入第一批资产到启用自动化改密的完整落地路径,全程约半小时。
为什么要有一座"门禁岗亭",而不是一把"万能钥匙"
先做个比喻。直接给每个同事发服务器密码,相当于给每人都配了一把万能钥匙:使用不受控、行为不记录、密码更换全靠自觉。而 PAM 平台的思路是在人和服务器之间加一座"门禁岗亭"——所有人先刷卡进岗亭,再由岗亭替你开门。于是出现了四个核心变化:
- 人钥分离:真实密码只掌握在系统手里,员工拿到的是经过授权的访问通道。
- 全程录像:SSH/RDP 会话可回放,命令可检索,出事后有据可查。
- 权限可控:谁能在什么时间段访问哪台机器,由授权规则决定。
- 密码可轮换:账号密码可以按计划自动更换,杜绝"万年不变"。
在 JumpServer 的架构里,几个组件各司其职:Lina 提供 Web 管理界面,Luna 是浏览器里的 Web 终端,KoKo 负责 SSH/SFTP 等字符协议连接,Lion 负责 RDP/VNC 等图形协议,Chen 则负责浏览器里的数据库管理。理解了这个分工,后面部署时遇到"组件状态"就不会一头雾水。
下面我们直接进入实操。本文采用"最小可用 → 接入资产 → 自动化"的三段式递进,每完成一段,JumpServer 就离"正式上岗"更近一步。
第一步:在一台裸机上把 JumpServer 跑起来
环境清单与检查
不需要昂贵的硬件。官方建议一台 64 位 Linux 服务器,4 核 8G 内存起步即可;生产环境建议磁盘用 SSD。部署前用一分钟确认三件事:
| 检查项 | 建议值 | 说明 |
|---|---|---|
| 操作系统 | CentOS 7+ / Ubuntu 20.04+ | 内核较新的发行版均可 |
| Python | 3.8+ | 源码部署必需 |
| 依赖服务 | PostgreSQL / MySQL + Redis | JumpServer 的存储与消息队列 |
💡 小提示:数据库和 Redis 可以先用 Docker 起在本机,把端口暴露给 JumpServer 即可,后续再迁移到独立实例,不影响本文的部署逻辑。
拉取源码并生成配置
先克隆项目仓库:
git clone https://gitcode.com/GitHub_Trending/ju/jumpserver
cd jumpserver
仓库根目录自带一份配置模板 config_example.yml,我们基于它生成自己的配置文件:
cp config_example.yml config.yml
打开 config.yml,你需要至少填三个值。第一个是加密密钥 SECRET_KEY,生产环境务必用随机串,可以用下面这条命令生成:
cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 49; echo
第二个是 BOOTSTRAP_TOKEN,它是 KoKo、Guacamole 等组件注册服务账号用的预共享令牌,同样用随机串。第三个是数据库密码 DB_PASSWORD,以及 Redis 的地址和密码(如果设置了的话)。模板里默认监听 8080 端口,如果和你现有服务冲突,修改 HTTP_LISTEN_PORT 即可。
安装依赖并启动
按项目 requirements/ 目录下的清单安装 Python 依赖后,用仓库自带的 jms 命令一键拉起全部核心服务:
python jms start all -d
jms 脚本(对应仓库根目录的 jms 文件)启动时会做一系列"自检动作":先检查数据库连通性(最多重试 60 次),然后执行数据表迁移、收集静态文件、下载 IP 库、安装内置 Applet。第一次启动看到日志里出现 Database connect success 和迁移完成的提示,说明核心链路已经打通。
浏览器访问 http://服务器IP:8080,使用默认账号 admin / ChangeMe 登录。首次登录系统会强制要求修改密码,这是 JumpServer 的安全基线,别跳过。
⚠️ 如果你的服务日志始终停在
Connection database failed, exit,八成是数据库地址、端口或密码没写对。记住:JumpServer 不会自动创建数据库,请先手动建好库(例如CREATE DATABASE jumpserver;)再启动。
第二步:把第一台服务器"交"给 JumpServer
平台能登录后,我们来做最关键的一件事:接入第一批资产。在左侧菜单进入"资产管理",创建资产时填写主机名、IP、端口和平台类型即可。对于 Linux 主机,选择 Linux 平台;Windows 主机则选择 Windows,JumpServer 会自动匹配对应的连接协议(Linux 默认 SSH,Windows 默认 RDP/SSH)。
接着为该资产创建"账号"——也就是登录这台机器的真实用户名和密码或密钥。这一步做完,授权是最后一道闸门:在"资产授权"中,把刚创建的账号授权给某个用户或用户组。从此该用户登录 JumpServer 后,只能在授权列表里看到这棵树,看不到也不存在其他资产。
验证连通性是接入后必做的一步。在资产详情里点击"测试连通性",后端会触发一个 Ansible 任务。这个任务在源码里的位置是 apps/assets/tasks/ping.py,它被声明在 queue='ansible' 的独立队列上执行,避免占用主业务线程:
@shared_task(
verbose_name=_('Test assets connectivity'),
queue='ansible',
)
def test_assets_connectivity_task(asset_ids, org_id, task_name=None):
...
quickstart_automation(task_name, AutomationTypes.ping, task_snapshot)
💡 如果测试结果一直"超时",先排查目标机器的 22 端口是否对本机放行,再确认系统账号的认证方式是否与你在 JumpServer 里填写的一致。连通性测试本质就是一次真实的 SSH 登录尝试,任何一端不匹配都会失败。
第三步:让 JumpServer 的 Ansible 引擎替你干脏活
接入资产只是开始,JumpServer 真正值钱的能力是自动化。日常最刚需的两个场景是:批量修改密码、批量推送新账号。这两项都依赖内置的 Ansible 运行引擎。
在 JumpServer 里新建"自动化任务",选择"改密"或"推送账号",圈定目标资产和账号,设置执行周期,剩下的交给系统。它会基于目标平台的预设连接参数生成 playbook 并执行。不同平台怎么连、用什么 shell,定义在 apps/assets/const/host.py 中:
cls.WINDOWS: {
'ansible_config': {
'ansible_shell_type': 'cmd',
'ansible_connection': 'smart',
},
},
而运行器本身采用了懒加载接口设计,真正的执行器按需创建,定义在 apps/ops/ansible/interface.py:
class RunnerInterface:
def __init__(self, runner_type, gateway_proxy_host='127.0.0.1'):
if not issubclass(runner_type, BaseRunner):
raise TypeError(f'{runner_type} can not cast to {BaseRunner}')
self._runner_type = runner_type
self._gateway_proxy_host = gateway_proxy_host
def run(self, **kwargs):
runner_type = self.get_runner_type()
runner = runner_type(**kwargs)
return runner.run()
对普通用户而言,你不需要看懂这些代码,只要知道:自动化任务有独立的超时体系、独立的队列和黑名单防护即可。比如 SECURITY_COMMAND_BLACKLIST 会在执行命令前拦截 reboot、shutdown、dd 这类高危命令,相当于给自动化也上了把锁。
落地调优:三个值得立刻调整的配置项
部署能用和部署好用是两回事。下面三个配置在 config.yml 里改完重启即可生效,建议直接照抄进自己的配置。
1. 给自动化任务设定"熔断"上限。 大批量改密时,如果某台机器卡住不响应,任务会一直占着执行线程。config_example.yml 里已经预留了一组超时参数,建议开启:
# 单台主机执行单个 task 的默认最长时间
ANSIBLE_AUTOMATION_TASK_TIMEOUT: 300
# 整个自动化任务的总时长上限,超过即终止剩余批次
ANSIBLE_AUTOMATION_TOTAL_TIMEOUT: 21600
# 连续无输出即判定卡死
ANSIBLE_RUNNER_IDLE_TIMEOUT: 900
2. 开启全局 MFA。 堡垒机最大的价值是"守门",如果门卫自己只用弱密码,一切白搭。在安全设置中把 SECURITY_MFA_AUTH 设为全局开启,并让用户绑定 OTP 验证器。绑定流程和手机验证码界面如下,扫码后把 6 位动态码填入即可完成绑定。
3. 收敛会话与上传限制。 建议显式设置 SESSION_COOKIE_AGE(默认一天)和 FILE_UPLOAD_SIZE_LIMIT_MB(默认 200),避免会话长期有效和超大文件传输拖垮磁盘。如果对登录地区有合规要求,还可以研究 SECURITY_LOGIN_IP_WHITE_LIST 等登录限制参数。
常见错误与修复:部署踩坑快查表
把高频问题按"现象 → 原因 → 处理"整理成一张表,遇到问题直接对号入座:
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
| 启动即报找不到配置文件 | 未执行 cp config_example.yml config.yml | 生成配置文件并填入密钥后重启 |
日志反复 Connection database failed | 数据库未建、端口不通或密码错误 | 先 CREATE DATABASE jumpserver;,再核对连接串 |
| 服务启动后秒退 | 端口被占用或依赖缺失 | 查看 data/logs/ 下的运行日志定位具体异常 |
| 资产连通性测试一直超时 | 目标机 22 端口未放行、账号凭证不符 | 确认网络与凭据,再触发一次测试 |
| Ansible 执行报权限不足 | 目标机的 sudo 未配置免密 | 在目标机 visudo 中加入 username ALL=(ALL) NOPASSWD: ALL |
| 忘记管理员密码 | 日常运维常见操作失误 | 使用仓库内的 utils/change_user_password.py 重置 |
另外提醒一点:JumpServer 的数据都在数据库里,养成定期备份的习惯非常划算。仓库自带的 utils/backup_db.sh 就是为此准备的,生产环境建议配合 crontab 定时执行。
收尾与后续路线
回头看这半小时做的事:装好一台可用的开源堡垒机,接入了第一批服务器,打开了自动化改密的大门,还顺手加固了登录环节。至此,"谁在什么时间用什么身份访问了哪台机器"终于有了完整的记录和管控,凌晨两点救火的故事也有了更稳妥的结局。
接下来可以沿着这几条线继续深入:
- 对接企业账号体系:LDAP/AD、OIDC、CAS、SAML2 等认证方式都内置支持,配置入口在 config_example.yml 的
AUTH_*段落; - 接入 K8s 与数据库:在资产类型中选择 Kubernetes 或 MySQL/PostgreSQL,体验浏览器内直接运维;
- 关注安全基线:SECURITY.md 里列出了项目维护者建议的安全实践,上线前值得通读一遍;
- 想要参与项目或深入源码:从 CONTRIBUTING.md 开始,改密、审计、资产模块都在
apps/目录下,目录命名与业务一一对应,上手成本不高。
服务器和密码不应该成为团队里"约定俗成的潜规则"。用 JumpServer 把访问收口,把审计留痕,把密码交给系统自动轮换——这才是现代运维该有的样子。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





