ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

JumpServer API实战:自动化临时授权与资产纳管

JumpServer API实战:自动化临时授权与资产纳管 接手公司运维平台的第二年最让我觉得“这活儿不该人干”的就是每周五下午集中开临时权限。十几个研发轮流申请登录测试服务器管理员在JumpServer里反复点鼠标——选资产、勾账号、设有效期、等审批一轮下来半小时过去了还容易漏。后来我把这套流程全部换成了JumpServer API调用从申请到授权完成压缩到几十秒审计记录也顺带留底了。这篇文章不是把官方文档抄一遍而是结合我在生产环境里实际用过的接口、踩过的坑和完整的自动化思路来写。不管你是运维、安全还是平台开发只要想把堡垒机从“手动操作台”升级成“可编程入口”这篇都能拿来当起点。我以JumpServer v3.x为主如果你还在用v2.x部分路径有差异但核心逻辑是一样的。1. 在动手写API之前先搞清楚JumpServer的权限金字塔1.1 堡垒机管的不是机器是“谁能用什么账号连哪台机器”很多人第一次打开JumpServer API文档时会被一堆英文单词劝退Asset、Account、Node、User、System User、Asset Permission、Ticket……但把这些概念翻译成人话其实就是一个金字塔。最底层是资产Asset就是被纳管的服务器、数据库、网络设备。资产不是孤立的它们挂在节点Node下面节点就是文件夹方便你按机房、项目、环境把资产分门别类。每个资产上面还有账号Account比如root、admin、oracle这种登录身份账号本身还分普通账号和特权账号。再往上是人User用堡垒机登录的都是用户用户可以有角色角色决定了这个人能不能看到管理菜单而不是决定他能连哪台机器。真正决定“谁能连哪台机器”的是中间这层——授权策略Asset Permission。一条授权策略把这几个东西绑定在一起哪些用户、在什么时间段内、可以连接哪些资产、用资产上的哪个账号、允许做什么操作连接、上传文件、下载文件。所以你在调API时最核心的一条主线就是先有资产再把账号塞进资产然后创建用户最后写一条授权策略把前三者串起来。顺序错一步结果都会不对。1.2 高频场景API到底能替我们省下哪些脏活累活根据我自己的实践JumpServer API最适合干下面几类事用户入职和离职自动化HR系统或ITIL工单平台触发后自动创建堡垒机用户、分配默认角色离职时一键禁用或删除。临时授权工单闭环研发在工单系统提交申请审批通过后由脚本自动创建一条短期授权策略到期自动失效。资产自动纳管云主机通过CMDB或云厂商API批量发现自动写入JumpServer并挂到对应节点省去手工录入。定期审计报表拉取会话记录、命令审计、登录日志生成日报或周报发给安全团队。紧急会话管控发现异常连接时通过API查询在线会话并强制断开。这些场景的共同点就是“重复、有规则、不能出错”。用UI点容易疲劳用API跑每次行为都可复现、可留痕。1.3 先找到你环境里的API文档入口JumpServer其实自带完整的交互式API文档。登录堡垒机后在浏览器地址栏直接访问/api/docs/就能看到当前版本下所有可用的接口列表Swagger风格的界面每个接口都能直接调试。注意不同版本接口前缀可能不一样常见的有/api/v1/、/api/v2/。我下面的示例统一用/api/v1/但实际调用前建议先用文档页确认。还有一点不要把API文档地址和Web Terminal搞混API文档返回的是JSON数据结构不是HTML管理页面。2. 拿到一把好用的钥匙认证与Token机制2.1 用账号密码换临时TokenJumpServer API的认证方式不算复杂大部分接口都要求你在请求头里带一个Token。最简单的获取方式就是调用认证接口用管理员账号登录curl -X POST https://jump.example.com/api/v1/authentication/auth/ \ -H Content-Type: application/json \ -d { username: admin, password: YourPassword }正常情况下响应会返回类似下面的JSON{ token: eyJhbGciOiJIUzI1NiIs..., session_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, user: { id: xxxxx, username: admin, name: 管理员 } }拿到token之后后续所有请求都要带上curl -X GET https://jump.example.com/api/v1/assets/assets/ \ -H Authorization: Bearer eyJhbGciOiJIUzI1NiIs...或者用它的别名头有些版本两种都认curl -X GET https://jump.example.com/api/v1/assets/assets/ \ -H X-JMS-Token: eyJhbGciOiJIUzI1NiIs...2.2 长期API Key适合脚本和定时任务临时Token有过期时间一般几十分钟到几小时不等。如果你的脚本是定时任务每天早上自动跑一次每次都先登录换Token也行但要处理密码过期、账号被锁等问题。更推荐的做法是在JumpServer页面的“个人中心”里生成一个长期API Key。入口路径大概是右上角头像 → 个人信息 → API Key / Token管理。创建后你会得到一串密钥字符串把这串字符串当成“客户端凭据”在请求头里带上即可。注意这个Key只在创建时展示一次之后就没法再看到了务必备份到自己的凭据管理工具里。长期API Key的好处是不用反复登录适合跑无人值守的定时任务。坏处是权限粒度通常绑定的是创建者本身的权限所以建议用专门的“服务账号”来申请这个Key而不是拿管理员日常账号去申请。2.3 请求头、Content-Type和字符编码的细节在实际调用中我遇到过几个很隐蔽的小问题Content-Type必须显式声明如果你用requests库或Postmanapplication/json一般会自动带上。但如果用HttpWebRequest或一些老代码忘记带这个头服务端会返回400提示JSON解析失败。响应编码统一UTF-8JumpServer返回的数据里中文用户名、资产名很容易有编码问题脚本要在请求头里带上Accept: application/json解析时强制用UTF-8。HTTPS证书公司内网如果用的自签名证书脚本里记得加verifyFalse但这是下策建议把证书链配置好避免安全扫描被扣分。另一个细节是注销。临时Token用完后可以调DELETE /api/v1/authentication/auth/主动失效防止Token泄露风险。但长期API Key一般不用调删除接口直接在页面里注销即可。3. 管资产不是遍历IP要把资产、账号、节点串起来3.1 查询资产列表先学会分页和筛选资产接口的核心URL是/api/v1/assets/assets/常用的查询参数如下limit每页数量默认10最大可以调大。offset跳过前面多少条。search模糊搜索匹配主机名、IP地址、备注等字段。order排序字段比如-date_created按创建时间倒序。实际请求示例curl -X GET https://jump.example.com/api/v1/assets/assets/?limit100offset0searchweb \ -H Authorization: Bearer TOKEN响应体里有两个关键字段一个是count总条数一个是results当前页数据。每个资产对象里带有id、name、address、protocols、nodes、platform等字段。这里有一个大坑id字段才是后续所有操作要用的UUID不是address也不是name。很多新手直接把name传进授权接口结果报错400。正确做法是先从列表接口里查出id再拿这个id去组装其他请求。3.2 创建资产和账号一次调用的正确姿势创建资产最简单的请求体是这样resp session.post(f{API_URL}/assets/assets/, json{ name: api-demo-dev-01, address: 192.168.10.88, protocols: [{name: ssh, port: 22}], nodes: [xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx], platform: GENERAL })protocols是协议列表SSH、RDP、VNC都可以在这里声明。nodes传的是节点UUID如果你不知道节点UUID可以先用查询接口找nodes session.get(f{API_URL}/assets/nodes/, params{search: 自建机房}).json() node_id nodes[results][0][id]资产创建出来之后还没有登录凭据需要紧接着创建账号resp session.post(f{API_URL}/assets/accounts/, json{ asset: asset_id, username: root, secret_type: password, secret: Root2024 })注意secret_type除了password还可能是ssh_keySSH私钥、token等。如果资产是Windows账号可能是administratorsecret_type也可能是password。3.3 把资产批量挂到节点树归档比录入更重要节点就是组织架构。我在生产环境里的经验是资产一旦多起来光靠“全量资产列表”根本没法授权因为授权策略不仅要指定资产还要考虑节点的继承关系。你可以提前用API把节点树建好比如resp session.post(f{API_URL}/assets/nodes/, json{ name: 电商项目, parent: 00000000-0000-0000-0000-000000000002 })这里的parent传父节点UUID顶层节点的parent一般是根节点ID具体以文档为准。然后在导入资产时把资产挂到对应节点下。这样后续授权时可以直接给整棵节点授权新加资产自动继承不用改策略这个技巧运维同学一定要掌握。小提示JumpServer的节点ID里00000000-0000-0000-0000-000000000001通常是默认根节点或未分组节点不同版本有区别不要硬编码手动查一次最保险。4. 用户、角色与授权策略权限系统的三种写法4.1 创建用户并绑定角色创建用户走/api/v1/users/users/resp session.post(f{API_URL}/users/users/, json{ username: zhangsan, name: 张三, email: zhangsanexample.com, mfa_enabled: True, source: local })创建成功后用户默认是普通用户。如果需要让某些人有资产管理权限要绑定角色。角色管理在/api/v1/users/roles/查出对应角色的id再通过用户详情接口更新用户角色字段。角色和授权是两码事。角色决定他能不能进“控制台”看到资产列表并编辑而授权决定他能不能通过Web Terminal连上某台服务器。所以创建用户之后别急着配权限先走授权策略。4.2 资产授权策略的完整字段这是整个JumpServer API里最重要、也最容易写错的一个接口/api/v1/perms/asset-permissions/。一个典型的授权策略请求体resp session.post(f{API_URL}/perms/asset-permissions/, json{ name: 研发-临时-需求ID-20240615, users: [user_uuid], assets: [asset_uuid], accounts: [account_uuid], date_start: 2024-06-15 00:00:00, date_expired: 2024-06-30 23:59:59, actions: [connect, upload_file, download_file], is_active: True })字段含义users授权给哪些用户传用户UUID列表。assets授权哪些资产传资产UUID列表。accounts授权用资产上的哪些账号这里传账号UUID列表。有些版本如果是“任意账号”可以留空或传特殊值具体看版本。actions允许的动作。connect是连接upload_file是上传download_file是下载。有些版本还有copy和paste。date_start / date_expired有效期。格式是yyyy-MM-dd HH:mm:ss我在这里踩过坑后面会说。如果你只想给用户“连接”权限动作列表里只留connect这是最安全的默认值。需要上传下载再单独加权限最小化原则在堡垒机里通用。4.3 工单加审批流把“提申请”变成API调用如果公司要求临时授权必须审批JumpServer里对应的概念是Ticket工单。调用/api/v1/tickets/tickets/可以创建一条工单resp session.post(f{API_URL}/tickets/tickets/, json{ ticket_type: apply_asset_permission, title: 研发-张三-临时连接测试服务器, body: 用于联调测试有效期一周, apply_permission: { name: 临时授权-张三-test01, users: [user_uuid], assets: [asset_uuid], accounts: [account_uuid], date_start: 2024-06-15 00:00:00, date_expired: 2024-06-21 23:59:59, actions: [connect] } })这样流程就变成工单系统审批通过 → 你的脚本自动在JumpServer创建一条授权工单 → 审批人或流程自动审批通过 → 授权策略生效。整个过程可控、可追溯。如果你希望完全自动化也可以在JumpServer里把审批流配置成“自动通过”然后把创建授权策略的API直接封装给你的内部系统调用。5. 会话、命令与审计API不只是配置机器人5.1 查询和强制中断在线会话运维过程中最紧急的场景就是“有人连了服务器疑似违规操作立刻断开”JumpServer API提供了会话管理接口/api/v1/terminal/sessions/。查询在线会话resp session.get(f{API_URL}/terminal/sessions/, params{ is_finished: false, limit: 50 })结果里每条会话记录包含id、user、asset、account、protocol、date_start等字段。找到问题会话后强制断开resp session.post(f{API_URL}/terminal/sessions/{session_id}/terminate/)这个接口响应很快基本秒断。有一次我们收到安全告警说某台服务器从外网登录我直接用脚本查询JumpServer在线会话5秒内锁定会话ID并断开同时导出了这个会话的完整命令记录作为证据整个过程不到一分钟。5.2 快速执行命令把批量操作从“跳板机”变成“API”JumpServer v3.x里可以通过/api/v1/ops/command-executions/发起快速命令执行任务。什么意思你不需要人肉登到资产上敲命令而是让JumpServer调度器去指定资产上执行一条命令然后把结果收回来。resp session.post(f{API_URL}/ops/command-executions/, json{ assets: [asset_uuid], accounts: [account_uuid], command: uptime df -h, run_async: True, timeout: 30 })执行完成后可以查询执行结果确认每条命令在所有资产上的exit code和输出。这个功能非常实用比如批量排查服务器时间同步情况、批量修改配置文件、批量检查磁盘空间。但是要注意快速执行命令的权限本身就是高危操作账号必须使用堡垒机托管的授权账号命令内容要尽量收敛必要时候配合命令过滤器限制。5.3 命令过滤器与审计日志导出说到命令过滤JumpServer还有一个接口专门管理命令规则/api/v1/perms/command-filters/。你可以通过API创建高危命令过滤规则比如禁止rm -rf、禁止格式化、禁止修改root密码。审计日志的拉取核心是两个接口/api/v1/terminal/sessions/会话记录包括连接时间、断开时间、来源IP。/api/v1/audits/command-logs/部分版本路径有差异命令记录每条操作命令都有对应的时间、用户、资产、账号。我写过一个每周五下午自动执行的脚本把这周的会话和命令记录拉下来按用户分组生成Markdown报表发到安全组的邮箱。以前安全组同事每周要花半天手动导出现在打开邮件就有了。6. 实操复盘一份完整的开权限自动化脚本6.1 PythonRequests串联核心场景下面这段代码是我在生产环境跑过的简化版覆盖了“查节点→创建资产→创建账号→查用户→创建授权策略”这条完整链路import requests BASE_URL https://jump.example.com/api/v1 TOKEN 从认证接口或API Key管理页获取的token session requests.Session() session.headers.update({ Authorization: fBearer {TOKEN}, Content-Type: application/json }) # 1. 找到目标节点 nodes_resp session.get(f{BASE_URL}/assets/nodes/, params{search: 测试环境}) node_id nodes_resp.json()[results][0][id] # 2. 创建资产 asset_resp session.post(f{BASE_URL}/assets/assets/, json{ name: api-demo-dev-01, address: 192.168.10.88, protocols: [{name: ssh, port: 22}], nodes: [node_id], platform: GENERAL }) asset_id asset_resp.json()[id] # 3. 给资产创建账号 session.post(f{BASE_URL}/assets/accounts/, json{ asset: asset_id, username: root, secret_type: password, secret: TemporaryPass123! }) # 4. 查询或创建用户 user_resp session.get(f{BASE_URL}/users/users/, params{search: zhangsan}) if user_resp.json()[count] 0: user_resp session.post(f{BASE_URL}/users/users/, json{ username: zhangsan, name: 张三, email: zhangsanexample.com, source: local }) user_id user_resp.json()[results][0][id] # 5. 创建临时授权策略一周后自动失效 session.post(f{BASE_URL}/perms/asset-permissions/, json{ name: 临时授权-张三-api-demo-dev-01, users: [user_id], assets: [asset_id], date_start: 2024-06-15 00:00:00, date_expired: 2024-06-21 23:59:59, actions: [connect], is_active: True })脚本跑完张三就能在JumpServer页面上看到这台资产并直接连接权限到期自动消失不需要管理员再去手动删。6.2 调试技巧从状态码到响应体逐层排查写API脚本最怕的就是请求发过去返回一个不痛不痒的400。我总结了一套排查顺序401 UnauthorizedToken没带、Token过期、API Key被禁用了。先用文档页手动调一次认证接口确认Token能拿到再排查代码。403 Forbidden账号权限不足。比如普通用户调管理接口比如/assets/assets/的写操作需要管理员角色。解决方式是给服务账号绑定管理员角色或者在页面里检查账号的系统角色。400 Bad Request参数校验失败。最常见的是字段名拼错、日期格式不对、UUID不是合法的、某个枚举值不在选项内。建议把请求体复制到Swagger文档页里手动提交看具体提示。404 Not FoundURL路径不对或者UUID资源不存在。确认版本的前缀检查资源ID是不是从上一步响应的id字段取的。500 或 502后端服务问题可能是Celery任务没起来、数据库连接异常。这种一般不是你的请求有问题去JumpServer宿主机上看日志docker logs jumpserver-core --tail 100。另外一个实用技巧是开启requests的调试日志import logging logging.basicConfig(levellogging.DEBUG)它能打印完整的请求URL、请求头和响应体定位问题时比猜快得多。6.3 我在生产环境里踩过的五个坑最后分享几个只有在真实环境里才会踩到的坑坑一日期格式千万别用T。用Python的datetime.now().isoformat()生成的2024-06-15T12:00:00JumpServer的API不认必须格式化成2024-06-15 12:00:00。我在这个上面卡了半小时还是翻了Swagger文档才发现的。坑二账号UUID不是账号名。授权策略里的accounts字段要传账号资源的UUID不是root这种名字。如果是给整台资产的所有账号授权有些版本支持传空列表或特殊标识但不要想当然先用查询接口试一遍。坑三批量操作一定要看分页。默认一页10条导致我写过一个脚本看起来“所有资产都授权了”实际上只处理了前10条。现在我的习惯是写一个通用函数循环拉取所有分页def get_all(base): results [] offset 0 while True: resp session.get(base, params{offset: offset, limit: 100}).json() results.extend(resp[results]) if offset 100 resp[count]: break offset 100 return results坑四删授权策略前要先解绑关联工单。如果一条授权策略是通过工单自动生成的有些版本直接delete会有外键约束错误需要先把关联工单关闭或取消再删除策略。坑五是脚本在跑不是你账号和审计不能省。给脚本创建专门的系统用户不要复用员工账号。每次API调用尽量记录日志谁在什么时间调了什么接口、改了哪些资源出现问题才能回溯。最后再补一个我自己的习惯每隔一段时间我会把JumpServer API文档页整个翻一遍看看当前版本有没有新增接口。毕竟堡垒机这种基础安全设施版本升级之后接口行为可能会有变化定时检查一下自己的脚本有没有“带病运行”比到时候临时救火舒服得多。
返回列表