CI 服务为什么是高危目标
Jenkins 的脚本控制台可以在主节点上执行任意 Groovy 代码,等于远程命令执行;它的凭据插件里通常还存着代码仓库、镜像仓库与云平台的密钥。因此“暴露公网 + 允许匿名访问 + 插件版本滞后”这三件事凑在一起,就是一条通向生产环境的捷径。加固方向是收敛访问(管理界面只对运维网段开放)、强认证(禁用匿名并接入统一身份)、关闭或限制 CLI、并把版本与插件更新纳入常规维护。
基本信息
| 加固项 | CI 服务暴露面与权限收敛 |
|---|---|
| 适用平台 | Linux/Windows(Jenkins) |
| 权限要求 | Jenkins 管理员 |
| 达标判据 | 管理界面不暴露公网、无匿名权限、插件为较新版本 |
| 相关端口 | 8080 管理界面、50000 代理通信(如在使用) |
典型使用场景
- 暴露面巡检发现 Jenkins 对公网开放
- 等保与审计核查中确认 CI 系统权限设置
- 攻防演练前收敛最容易被拿下的服务
- 插件安全更新与版本升级的定期维护
- 凭据插件中长生命周期密钥的定期轮换
核查现状
核查现状
ss -tlnp | grep -E ':8080|:50000' # 监听地址:是否绑在所有网卡
curl -s --max-time 5 http://127.0.0.1:8080/api/json 2>/dev/null | head -c 200 # 未认证可读即匿名权限过大
curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 http://127.0.0.1:8080/ # 状态码:200 表示未登录即可访问
# 从外部网络对管理端口做一次可达性确认(自有资产、受控前提下)加固要点
加固要点
# 安全域:使用 Jenkins 自有用户库或 LDAP/SSO,禁用“任何用户可做任何事”
# 授权策略:Matrix-based,按项目与角色最小授权,匿名不给读取权限
# 关闭 CLI:启动参数加 -Djenkins.CLI.disabled=true
# 管理端口仅对运维网段开放:安全组与主机防火墙双层限制
systemctl restart jenkins # 改启动参数后重启并复测匿名访问风险点与对策
| 风险点 | 说明 | 对策 |
|---|---|---|
| 脚本控制台暴露 | 可执行任意 Groovy 代码等于命令执行 | 仅管理员可见,并限制管理界面来源 |
| 匿名可读 | 可枚举任务名、配置与构建参数 | 关闭匿名读取,改为登录可见 |
| 凭据插件存密钥 | 一旦拿下主节点即获得多平台凭据 | 最小授权、定期轮换、限制使用范围 |
| 插件版本滞后 | 历史插件漏洞数量多 | 定期更新插件与主版本 |
| 50000 代理端口 | 代理通信端口同样可能被滥用 | 仅内网开放,必要时启用 TLS |
历史 Jenkins 漏洞多与未授权访问和插件有关,暴露在公网时被扫描利用只是时间问题。除收敛访问与升级版本外,还应对构建节点做隔离:主节点不放业务数据,构建凭据按项目最小化,避免一台机器失守等于全部环境失守。
“匿名只读”常被认为无害,但任务名、仓库地址、构建参数与环境变量名都能被枚举,这些信息足以支撑后续针对性攻击。定期用未登录的会话访问一次界面与接口,是验证匿名权限是否真正关闭的最直接办法。