安全最佳实践 #
本节将介绍Jenkins安全加固的最佳实践,帮助您构建安全的CI/CD环境。
安全原则 #
1. 最小权限原则 #
只授予完成任务所需的最小权限。
2. 纵深防御 #
多层安全防护,不依赖单一安全措施。
3. 安全默认 #
默认配置应该是安全的。
4. 定期审计 #
定期检查和审计安全配置。
系统安全 #
更新Jenkins #
定期更新Jenkins到最新稳定版本:
bash
# Docker方式
docker pull jenkins/jenkins:lts
docker stop jenkins
docker rm jenkins
docker run -d --name jenkins jenkins/jenkins:lts
# WAR包方式
wget https://updates.jenkins.io/latest/jenkins.war
systemctl restart jenkins
更新插件 #
定期更新插件:
- 进入 Manage Jenkins → Manage Plugins
- 检查 Updates 标签
- 更新所有插件
禁用不必要的功能 #
text
Manage Jenkins → System:
☐ Enable CLI over remoting
☐ Enable Jenkins CLI
禁用旧协议 #
text
Manage Jenkins → System → Agent Protocols:
☐ JNLP-connect
☐ JNLP2-connect
☑ JNLP4-connect
认证安全 #
强密码策略 #
安装 Strict Crumb Issuer 插件:
text
Manage Jenkins → System → CSRF Protection:
☑ Enable CSRF Protection
Crumb Issuer: Strict Crumb Issuer
☑ Validate Crumb and Session ID
双因素认证 #
安装 Google Authenticator 插件:
text
Manage Jenkins → System → Security Realm:
Security Realm: Google Authenticator
禁用匿名访问 #
text
Manage Jenkins → Configure Global Security:
Authorization: Logged-in users can do anything
☐ Allow anonymous read access
密码策略 #
安装 Password Strategy 插件:
text
Manage Jenkins → System:
Password Policy:
Minimum length: 12
Require uppercase: true
Require lowercase: true
Require digit: true
Require special character: true
授权安全 #
使用角色策略 #
text
Authorization: Role-Based Strategy
权限分离 #
text
管理员角色:
- Overall/Administer
开发者角色:
- Job/Read
- Job/Build
- Job/Configure
- Job/Workspace
查看者角色:
- Overall/Read
- Job/Read
项目级权限 #
对敏感项目设置项目级权限:
text
Job Configuration:
☑ Enable project-based security
配置允许的用户和权限
凭据安全 #
使用凭据管理 #
不要在代码中硬编码敏感信息:
groovy
// 不推荐
sh 'deploy.sh --password mypassword'
// 推荐
withCredentials([string(credentialsId: 'db-password', variable: 'PASSWORD')]) {
sh 'deploy.sh --password $PASSWORD'
}
凭据轮换 #
定期轮换凭据:
groovy
import jenkins.model.*
import com.cloudbees.plugins.credentials.*
import com.cloudbees.plugins.credentials.impl.*
def updateCredential(String id, String newPassword) {
def domain = Domain.global()
def store = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()
def oldCred = CredentialsProvider.lookupCredentials(
StandardUsernamePasswordCredentials,
Jenkins.instance,
null,
null
).find { it.id == id }
def newCred = new UsernamePasswordCredentialsImpl(
CredentialsScope.GLOBAL,
id,
oldCred.description,
oldCred.username,
newPassword
)
store.updateCredentials(domain, oldCred, newCred)
}
外部凭据存储 #
使用HashiCorp Vault等外部凭据存储:
groovy
withVault(configuration: [
engineVersion: 2,
path: 'secret/jenkins'
], vaultSecrets: [
[
path: 'database',
secretValues: [
[vaultKey: 'password', envVar: 'DB_PASSWORD']
]
]
]) {
sh 'deploy.sh'
}
网络安全 #
HTTPS配置 #
使用HTTPS访问Jenkins:
nginx
server {
listen 443 ssl http2;
server_name jenkins.example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name jenkins.example.com;
return 301 https://$server_name$request_uri;
}
禁用HTTP #
text
Manage Jenkins → System:
Jenkins URL: https://jenkins.example.com/
限制访问IP #
nginx
location / {
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
proxy_pass http://localhost:8080;
}
防火墙配置 #
bash
# 只允许内网访问
iptables -A INPUT -p tcp --dport 8080 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP
Agent安全 #
禁用Master构建 #
text
Manage Jenkins → System:
# of executors: 0
Agent认证 #
text
Manage Jenkins → Configure Global Security:
☑ Enable Agent → Master Access Control
☑ Require authentication for agent connections
Agent协议 #
只使用安全的Agent协议:
text
Manage Jenkins → System → Agent Protocols:
☐ JNLP-connect
☐ JNLP2-connect
☑ JNLP4-connect
Agent权限 #
限制Agent的访问权限:
text
Manage Jenkins → Manage Nodes:
Node Configuration → Node Properties:
☑ Tool Locations
☑ Environment variables
日志和监控 #
审计日志 #
安装 Audit Trail 插件:
text
Manage Jenkins → System → Audit Trail:
☑ Log all requests
Log file: /var/log/jenkins/audit.log
安全日志 #
配置安全相关日志:
text
Manage Jenkins → System Log:
Add Logger:
Logger: hudson.security
Level: FINE
监控告警 #
安装 Monitoring 插件:
text
Manage Jenkins → Monitoring:
监控系统资源和JVM状态
备份和恢复 #
备份配置 #
定期备份Jenkins配置:
bash
#!/bin/bash
BACKUP_DIR="/backup/jenkins"
DATE=$(date +%Y%m%d)
# 备份配置
tar -czf ${BACKUP_DIR}/jenkins-config-${DATE}.tar.gz \
${JENKINS_HOME}/config.xml \
${JENKINS_HOME}/jobs \
${JENKINS_HOME}/users \
${JENKINS_HOME}/credentials.xml
# 备份密钥
tar -czf ${BACKUP_DIR}/jenkins-secrets-${DATE}.tar.gz \
${JENKINS_HOME}/secrets
# 保留最近30天的备份
find ${BACKUP_DIR} -name "*.tar.gz" -mtime +30 -delete
恢复配置 #
bash
# 恢复配置
tar -xzf jenkins-config-20260328.tar.gz -C ${JENKINS_HOME}
# 恢复密钥
tar -xzf jenkins-secrets-20260328.tar.gz -C ${JENKINS_HOME}
# 重启Jenkins
systemctl restart jenkins
安全检查清单 #
系统安全 #
- [ ] 更新Jenkins到最新版本
- [ ] 更新所有插件
- [ ] 禁用不必要的功能
- [ ] 禁用旧协议
认证安全 #
- [ ] 配置认证方式
- [ ] 禁用匿名访问
- [ ] 实施强密码策略
- [ ] 启用双因素认证
授权安全 #
- [ ] 配置授权策略
- [ ] 使用角色管理
- [ ] 遵循最小权限原则
- [ ] 配置项目级权限
凭据安全 #
- [ ] 使用凭据管理
- [ ] 定期轮换凭据
- [ ] 考虑外部凭据存储
- [ ] 不在日志中暴露凭据
网络安全 #
- [ ] 启用HTTPS
- [ ] 配置防火墙
- [ ] 限制访问IP
- [ ] 配置反向代理
Agent安全 #
- [ ] 禁用Master构建
- [ ] 启用Agent认证
- [ ] 使用安全协议
- [ ] 限制Agent权限
日志和监控 #
- [ ] 启用审计日志
- [ ] 配置安全日志
- [ ] 设置监控告警
- [ ] 定期检查日志
备份和恢复 #
- [ ] 定期备份配置
- [ ] 备份密钥文件
- [ ] 测试恢复流程
- [ ] 异地备份
安全加固脚本 #
groovy
import jenkins.model.*
import hudson.security.*
def instance = Jenkins.getInstance()
// 禁用CLI
instance.setCliEnabled(false)
// 设置安全域
def realm = new HudsonPrivateSecurityRealm(false)
instance.setSecurityRealm(realm)
// 设置授权策略
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
instance.setAuthorizationStrategy(strategy)
// 禁用JNLP
instance.setSlaveAgentPort(-1)
// 保存配置
instance.save()
println "Security hardening completed!"
下一步学习 #
小结 #
- 安全是一个持续的过程
- 遵循最小权限原则
- 定期更新和审计
- 使用HTTPS和安全协议
- 保护凭据安全
- 监控和日志审计
- 定期备份配置
最后更新:2026-03-28