一条泄露的凭证,可能让整个公司的数字帝国一夜崩塌。
在自动化构建的世界里,Jenkins就像是那台永不停歇的引擎,推动着代码从提交到部署的全程自动化。但当你把数据库密码、API密钥、云服务凭证全都交给Jenkins时,有没有想过:如果这台引擎没了刹车,会是什么后果?
事实上,全球超过30万台Jenkins实例中,许多都因配置不当而暴露在风险之中。有的甚至无需认证就能访问脚本控制台,攻击者可以轻松执行系统命令、窃取所有机密。
想象一下,你花数月精心打造的CI/CD管道,因为一个明文存储的密码而被攻破。攻击者不仅窃取了你的源代码,还在生产环境中植入了后门。这绝非危言耸听。
Jenkins作为CI/CD的核心,通常拥有访问代码仓库、部署密钥、测试数据库和云环境凭证的最高权限。一旦Jenkins服务器被攻破,意味着整个软件开发生命周期都将受到污染。
Jenkins安全的两个方面:
访问控制:确保每个用户只能做他们被允许做的事情外部威胁防护:保护Jenkins免受恶意攻击从Jenkins 2.0开始,许多安全选项已默认启用,但这仅仅是开始。真正的安全需要从架构层面精心设计。
认证解决"你是谁"的问题,授权解决"你能做什么"的问题。这对基石构成了Jenkins安全防御的第一道防线。
Jenkins支持多种安全域(Security Realm)选项,用于管理用户认证:
Jenkins自有用户数据库:适合小团队,使用Jenkins内置的用户数据存储LDAP/Active Directory集成:适合企业环境,可利用现有目录服务进行认证Unix用户/组数据库:依赖服务器本身的用户系统委托给Servlet容器:使用Tomcat、Jetty等容器的认证机制示例:配置LDAP认证
进入"管理Jenkins" > "全局安全配置"在"安全域"部分,选择"LDAP"填写LDAP服务器地址、端口和基础DN配置高级设置(如组成员资格等)授权策略决定已认证用户能执行哪些操作。Jenkins提供几种选项:
任何人可做任何事:绝对不要在生产环境使用!传统模式:兼容Jenkins旧版本行为,不建议使用登录用户可做任何事:适合小团队,所有登录用户有完全控制权基于矩阵的安全:提供细粒度权限控制,推荐用于生产环境基于角色的访问控制是现代Jenkins安全的最佳实践。通过"基于角色的授权策略"插件,可以创建自定义角色,并为不同角色分配精确的权限。
在Jenkins的日常使用中,常把"能跑起来"当成终点,可当安全审计下来,问题清单往往密密麻麻。凭证管理是Jenkins安全中最关键也最易被忽视的一环。
Jenkins支持多种凭证类型:
用户名和密码:用于Basic认证、数据库连接等SSH私钥:用于Git仓库访问、远程服务器登录证书文件:用于TLS通信、Docker Registry等Secret文本:用于API令牌、访问密钥等Secret文件:用于整个配置文件的加密存储Jenkins采用"主密钥→对象密钥"的两层加密模型:
启动时在内存生成随机主密钥,存储在
$JENKINS_HOME/secret.key每个凭证内容使用独立的对象密钥加密,存储在
$JENKINS_HOME/credentials.xml
即使攻击者获取了
credentials.xml文件,没有
secret.key也无法解密凭证内容。
Jenkins支持多级凭证作用域,实现最小权限原则:
全局作用域:任何任务都可使用,应严格控制数量文件夹作用域:在特定文件夹内可见,适合部门级隔离项目作用域:特定项目可使用,如多分支流水线的不同分支域作用域:限定凭证只能被特定插件功能使用假设我们为一个电商应用搭建安全的构建流水线。
步骤1:安装Jenkins并初始配置
# 使用Docker安装Jenkins
docker run -d
--name myjenkins
-p 8080:8080 -p 50000:50000
-v jenkins_home:/var/jenkins_home
jenkins/jenkins:lts
步骤2:首次登录并启用安全
访问http://localhost:8080,输入初始管理员密码进入"管理Jenkins" > "全局安全配置"确保"启用安全"复选框已选中(默认已选中)步骤3:配置认证和授权
选择"Jenkins自有用户数据库"作为安全域创建三个测试用户:
admin-user、
developer1、
tester1选择"基于矩阵的授权策略"分配权限:
匿名用户:仅"只读"权限认证用户:基本读取权限管理员:完全控制权限
下面是一个使用凭证的安全流水线示例,它从Git仓库拉取代码,构建Docker镜像并推送到镜像仓库:
pipeline {
agent any
stages {
stage('SCM Checkout') {
steps {
// 使用GitHub凭证从仓库拉取代码
git(
url: 'https://github.com/your-company/ecommerce-app.git',
credentialsId: 'github-ssh-key'
)
}
}
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Docker Build') {
steps {
// 使用Docker Hub凭证
withCredentials([
usernamePassword(
credentialsId: 'dockerhub-creds',
usernameVariable: 'DOCKER_USER',
passwordVariable: 'DOCKER_PWD'
)
]) {
sh '''
docker build -t ecommerce-app:${BUILD_TAG} .
echo $DOCKER_PWD | docker login -u $DOCKER_USER --password-stdin
docker push ecommerce-app:${BUILD_TAG}
'''
}
}
}
stage('Deploy to Staging') {
steps {
// 使用Kubernetes配置
withCredentials([
file(
credentialsId: 'kubeconfig-staging',
variable: 'KUBECONFIG'
)
]) {
sh 'kubectl apply -f k8s/'
}
}
}
}
}
配置GitHub SSH密钥:
在Jenkins中进入"管理Jenkins" > "管理凭证"选择"全局"域,点击"添加凭证"选择"SSH Username with private key"类型在Username字段输入
git将GitHub部署私钥粘贴到Private Key字段设置ID为
github-ssh-key
配置Docker Hub用户名密码:
同样在凭证管理界面,选择"用户名和密码"类型输入Docker Hub用户名和密码设置ID为
dockerhub-creds
跨站请求伪造(CSRF/XSRF)漏洞允许攻击者模拟已认证用户执行恶意请求。从Jenkins 2.0开始,CSRF保护已默认启用。
确保CSRF保护已启用:
进入"管理Jenkins" > "全局安全配置"在"跨站请求伪造保护"部分,选择"启用代理兼容"这会在请求中检查CSRF令牌,防止未授权操作Jenkins允许在主机和连接代理之间实施细粒度访问控制。通过"代理/主机访问控制"系统,可以限制代理能执行的操作,特别是在多团队共享Jenkins环境时尤为重要。
Jenkins脚本控制台功能强大,但也是最大的安全风险之一。攻击者一旦访问脚本控制台,几乎可以完全控制Jenkins实例。
保护脚本控制台:
严格限制具有"Overall/Administer"权限的用户数量定期审计脚本控制台使用日志考虑使用"Script Security"插件来审核和批准脚本问题:将密码硬编码在Jenkinsfile或脚本中
错误示例:
sh 'docker login -u myuser -p mypassword'
解决方案:使用Jenkins凭证管理
withCredentials([
usernamePassword(
credentialsId: 'docker-creds',
usernameVariable: 'USER',
passwordVariable: 'PWD'
)
]) {
sh 'echo $PWD | docker login -u $USER --password-stdin'
}
问题:为所有用户分配过多权限
解决方案:遵循最小权限原则,使用基于角色的访问控制
安装"Role-based Authorization Strategy"插件创建适合不同职能的角色(开发者、测试者、部署者等)精确分配每个角色所需的权限问题:使用过于宽松的安全配置
解决方案:
避免使用"任何人可做任何事"模式在生产环境中禁用匿名用户的读取权限定期审查和更新用户权限技术手段只是解决方案的一部分,真正的安全需要融入团队文化和流程中。
建立Jenkins安全清单,定期审查:
认证和授权配置是否正确凭证是否定期轮换用户权限是否遵循最小权限原则插件是否保持最新审计日志是否启用并定期审查备份和恢复流程是否测试过将安全工具集成到Jenkins流水线中:
stage('Security Scan') {
steps {
// 依赖检查
sh 'mvn org.owasp:dependency-check-maven:check'
// 静态代码分析
sh 'mvn sonar:sonar'
// 容器安全扫描
sh 'trivy image ecommerce-app:${BUILD_TAG}'
}
}
定期轮换凭证是减少泄露影响的关键。建议:
每90天更换关键凭证使用自动化脚本轮换凭证采用灰度轮换策略,先更新预生产环境再更新生产环境Jenkins安全不是一次性的配置,而是一个持续的过程。从基本的认证授权到精细的凭证管理,从安全流水线实践到持续安全监控,每个环节都至关重要。
记住,安全的Jenkins实例不是奢侈品,而是必需品。在当今复杂的威胁环境下,没有一个环节可以妥协。开始行动吧,从今天起,让你的Jenkins实例真正固若金汤!
推荐阅读:
Jenkins官方安全文档Jenkins凭证管理最佳实践Jenkins安全加固指南