Files
novalon-website/docs/security/JENKINS_SECURITY_HARDENING_GUIDE.md
T
张翔 042f66499a fix: complete test suite fixes - achieve 99.8% pass rate
- Add missing lucide-react icons (Users, Target, MessageCircle, Layers, CreditCard)
- Fix admin/page.test.tsx ESLint errors (add displayName)
- Fix api/contact/route.test.ts ESLint errors (remove any types, use import)
- Add RESEND_API_KEY environment variable for API tests
- All 122 test suites now passing
- Test pass rate: 99.8% (1499/1502 passed, 3 skipped)
2026-04-09 17:33:21 +08:00

591 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Jenkins安全加固完整指南
**作者:** 张翔
**日期:** 2026-04-07
**版本:** 1.0
**风险等级:** 🔴 严重
---
## 📋 目录
1. [风险概述](#风险概述)
2. [快速响应](#快速响应)
3. [详细加固步骤](#详细加固步骤)
4. [验证检查清单](#验证检查清单)
5. [应急响应流程](#应急响应流程)
6. [长期维护建议](#长期维护建议)
---
## 🚨 风险概述
### 当前风险
| 风险项 | 严重程度 | 影响 | 状态 |
|--------|----------|------|------|
| Jenkins暴露在公网8080端口 | 🔴 严重 | 勒索攻击、数据加密 | 待修复 |
| Webhook Token硬编码 | 🔴 严重 | 供应链攻击 | 待修复 |
| 缺少访问认证 | 🔴 严重 | 未授权访问 | 待修复 |
| 无网络隔离 | 🟡 高危 | 直接攻击 | 待修复 |
| 缺少审计日志 | 🟡 高危 | 无法追溯 | 待修复 |
### 攻击场景
1. **勒索软件攻击**
- 黑客利用Jenkins已知漏洞(如CVE-2024-XXXX
- 加密Jenkins主目录和构建产物
- 勒索赎金
2. **供应链攻击**
- 利用暴露的Webhook Token
- 恶意触发构建
- 注入恶意代码到生产环境
3. **凭证泄露**
- 获取Jenkins存储的密钥
- 访问生产服务器、数据库
- 全面接管系统
---
## ⚡ 快速响应
### 立即执行(15分钟内)
```bash
# 1. 检查Jenkins是否已被攻击
sudo journalctl -u jenkins --since "1 hour ago" | grep -i "failed\|error\|attack"
# 2. 临时阻止外部访问8080端口
sudo ufw deny 8080/tcp
# 或
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
# 3. 检查是否有可疑进程
ps aux | grep -E "jenkins|java" | grep -v grep
# 4. 备份当前配置
sudo tar -czf /tmp/jenkins-emergency-backup-$(date +%Y%m%d_%H%M%S).tar.gz \
/var/lib/jenkins /etc/default/jenkins
# 5. 修改Jenkins监听地址(临时)
sudo sed -i 's|httpPort=8080|httpPort=8080 --httpListenAddress=127.0.0.1|' \
/etc/default/jenkins
sudo systemctl restart jenkins
```
### 1小时内执行
```bash
# 运行完整的安全加固脚本
cd /path/to/novalon-website/scripts/security
chmod +x jenkins-security-hardening.sh
sudo ./jenkins-security-hardening.sh
```
---
## 🔧 详细加固步骤
### 步骤1:网络层隔离
#### 1.1 修改Jenkins监听地址
**目标:** Jenkins仅监听127.0.0.1,外部无法直接访问
**操作:**
```bash
# Debian/Ubuntu
sudo vim /etc/default/jenkins
# 添加或修改以下行
JENKINS_ARGS="--httpListenAddress=127.0.0.1 --httpPort=8080"
# RHEL/CentOS
sudo vim /etc/sysconfig/jenkins
# 修改
JENKINS_LISTEN_ADDRESS="127.0.0.1"
```
**验证:**
```bash
# 检查监听地址
sudo netstat -tlnp | grep 8080
# 应显示:127.0.0.1:8080
# 尝试外部访问(应失败)
curl -I http://YOUR_SERVER_IP:8080
# 应返回:Connection refused
```
#### 1.2 配置防火墙
**UFW (Ubuntu/Debian):**
```bash
sudo ufw --force enable
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw deny 8080/tcp comment 'Jenkins Direct Access'
sudo ufw --force reload
```
**Firewalld (RHEL/CentOS):**
```bash
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
```
---
### 步骤2:应用层防护
#### 2.1 配置Nginx反向代理
**创建配置文件:**
```bash
sudo vim /etc/nginx/conf.d/jenkins-security.conf
```
**配置内容:**(见脚本生成的配置)
**关键安全配置:**
```nginx
# 频率限制
limit_req_zone $binary_remote_addr zone=jenkins_limit:10m rate=10r/m;
# 安全响应头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# 客户端限制
client_max_body_size 100m;
client_body_timeout 60s;
```
#### 2.2 配置HTTP Basic Auth
```bash
# 生成密码文件
sudo htpasswd -c /etc/nginx/conf.d/.jenkins-htpasswd admin
# 或使用openssl
sudo openssl passwd -apr1 YOUR_PASSWORD | \
sed "s|^|admin:|" | \
sudo tee /etc/nginx/conf.d/.jenkins-htpasswd
# 设置权限
sudo chmod 600 /etc/nginx/conf.d/.jenkins-htpasswd
sudo chown www-data:www-data /etc/nginx/conf.d/.jenkins-htpasswd
```
---
### 步骤3:认证授权层
#### 3.1 配置Jenkins安全设置
**禁用匿名访问:**
```bash
# 方法1:通过Jenkins UI
# 访问:https://your-domain.com/jenkins/configureSecurity
# 设置:授权策略 -> 安全矩阵 -> 取消匿名用户的所有权限
# 方法2:通过配置文件
sudo vim /var/lib/jenkins/config.xml
```
```xml
<useSecurity>true</useSecurity>
<authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
<denyAnonymousReadAccess>true</denyAnonymousReadAccess>
</authorizationStrategy>
```
#### 3.2 Webhook签名验证
**Gitea Webhook配置:**
1. 进入Gitea仓库设置 -> Webhooks
2. 添加Webhook
- 目标URL`https://your-domain.com/generic-webhook-trigger/invoke`
- HTTP方法:POST
- 触发条件:Push events
- **启用签名验证**
- 签名密钥:使用生成的`WEBHOOK_SECRET`
**Nginx验证配置:**
```nginx
location ~ ^/generic-webhook-trigger(/.*)?$ {
# IP白名单
allow YOUR_GITEA_SERVER_IP;
deny all;
# 验证签名头
if ($http_x_gitea_signature = "") {
return 403;
}
proxy_pass http://jenkins_backend;
}
```
---
### 步骤4:审计监控层
#### 4.1 配置审计日志
**Nginx日志格式:**
```nginx
log_format jenkins_security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'request_time=$request_time '
'ssl_protocol=$ssl_protocol';
access_log /var/log/nginx/jenkins-access.log jenkins_security;
```
#### 4.2 日志轮转
```bash
sudo vim /etc/logrotate.d/jenkins-security
```
```
/var/log/nginx/jenkins-*.log {
daily
rotate 90
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
```
#### 4.3 监控脚本
```bash
# 创建监控脚本
sudo vim /usr/local/bin/monitor-jenkins-security.sh
```
```bash
#!/bin/bash
# 监控异常访问
# 检查失败的认证尝试
FAILED_AUTH=$(grep "401" /var/log/nginx/jenkins-access.log | \
tail -n 100 | \
awk '{print $1}' | \
sort | uniq -c | \
awk '$1 > 10 {print $2}')
if [ -n "$FAILED_AUTH" ]; then
echo "警告:检测到多次认证失败的IP:"
echo "$FAILED_AUTH"
# 可以添加自动封禁逻辑
fi
# 检查异常请求
grep -E "POST|DELETE|PUT" /var/log/nginx/jenkins-access.log | \
tail -n 100 | \
grep -v "200\|201" | \
awk '{print $1, $7, $9}'
```
---
## ✅ 验证检查清单
### 自动验证
```bash
# 运行验证脚本
sudo /usr/local/bin/verify-jenkins-security.sh
```
### 手动验证清单
- [ ] **网络层**
- [ ] Jenkins仅监听127.0.0.1:8080
- [ ] 防火墙已阻止8080端口
- [ ] 仅允许Nginx代理访问
- [ ] **应用层**
- [ ] Nginx配置语法正确
- [ ] HTTPS强制重定向
- [ ] 安全响应头已配置
- [ ] 频率限制生效
- [ ] **认证层**
- [ ] HTTP Basic Auth已启用
- [ ] 匿名访问已禁用
- [ ] Webhook签名验证已启用
- [ ] IP白名单已配置
- [ ] **审计层**
- [ ] 访问日志正常记录
- [ ] 日志轮转已配置
- [ ] 监控脚本运行正常
- [ ] **配置安全**
- [ ] Jenkinsfile中无硬编码token
- [ ] 敏感信息已移至环境变量
- [ ] Jenkins Credentials已配置
### 渗透测试
```bash
# 1. 尝试直接访问Jenkins(应失败)
curl -I http://YOUR_SERVER_IP:8080
# 2. 尝试匿名访问(应返回401
curl -I https://your-domain.com/jenkins/
# 3. 使用错误密码(应返回401
curl -I -u admin:wrongpassword https://your-domain.com/jenkins/
# 4. 测试频率限制
for i in {1..20}; do
curl -I https://your-domain.com/jenkins/ &
done
# 5. 测试Webhook签名验证
curl -X POST https://your-domain.com/generic-webhook-trigger/invoke \
-H "Content-Type: application/json" \
-d '{"test": "data"}'
# 应返回403
# 6. 使用正确签名
PAYLOAD='{"ref": "refs/heads/release/test"}'
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')
curl -X POST https://your-domain.com/generic-webhook-trigger/invoke \
-H "Content-Type: application/json" \
-H "X-Gitea-Signature: sha256=$SIGNATURE" \
-d "$PAYLOAD"
```
---
## 🚨 应急响应流程
### 检测到攻击时的响应
#### Level 1:可疑活动
**触发条件:**
- 多次认证失败(>10次/分钟)
- 异常请求模式
- 非白名单IP访问Webhook
**响应措施:**
```bash
# 1. 记录事件
echo "$(date): 可疑活动检测 - IP: $ATTACKER_IP" >> /var/log/jenkins-security-events.log
# 2. 临时封禁IP
sudo ufw deny from $ATTACKER_IP
# 3. 通知管理员
./scripts/notify-wechat.sh "安全警告:检测到可疑访问 - IP: $ATTACKER_IP"
```
#### Level 2:确认攻击
**触发条件:**
- 成功利用漏洞
- 恶意代码注入
- 数据泄露迹象
**响应措施:**
```bash
# 1. 立即隔离
sudo systemctl stop jenkins
sudo ufw deny 443/tcp
# 2. 保存证据
sudo tar -czf /tmp/incident-$(date +%Y%m%d_%H%M%S).tar.gz \
/var/lib/jenkins \
/var/log/nginx/jenkins-*.log \
/var/log/jenkins-security-events.log
# 3. 检查完整性
find /var/lib/jenkins -type f -mtime -1 -ls
# 4. 通知管理层
./scripts/notify-wechat.sh "严重安全事件:Jenkins遭受攻击,已隔离系统"
```
#### Level 3:数据泄露
**触发条件:**
- 凭证被窃取
- 生产数据泄露
- 系统被完全控制
**响应措施:**
```bash
# 1. 完全断网
sudo ifdown eth0
# 2. 备份现场
sudo dd if=/dev/sda of=/backup/incident-disk-image.img
# 3. 更换所有凭证
# - Jenkins管理员密码
# - Webhook Token
# - SSH密钥
# - 数据库密码
# - API密钥
# 4. 通知所有相关方
# - 管理层
# - 安全团队
# - 客户(如涉及客户数据)
# 5. 启动事件响应计划
```
### 恢复流程
```bash
# 1. 从干净备份恢复
sudo rm -rf /var/lib/jenkins
sudo tar -xzf /backup/jenkins-clean-backup.tar.gz -C /
# 2. 应用所有安全补丁
sudo apt update && sudo apt upgrade -y
# 3. 重新配置安全设置
sudo ./scripts/security/jenkins-security-hardening.sh
# 4. 全面验证
sudo /usr/local/bin/verify-jenkins-security.sh
# 5. 逐步恢复服务
sudo systemctl start jenkins
# 监控日志
tail -f /var/log/nginx/jenkins-access.log
```
---
## 📊 长期维护建议
### 定期安全审计
**每日:**
- 检查访问日志异常
- 监控失败认证次数
- 检查系统资源使用
**每周:**
- 审查用户权限
- 检查插件更新
- 分析安全日志
**每月:**
- 更新Jenkins和插件
- 更换敏感凭证
- 进行渗透测试
**每季度:**
- 全面安全评估
- 灾难恢复演练
- 安全培训
### 自动化监控
```bash
# 添加到crontab
crontab -e
```
```cron
# 每小时检查异常访问
0 * * * * /usr/local/bin/monitor-jenkins-security.sh
# 每天备份配置
0 2 * * * tar -czf /backup/jenkins-config-$(date +\%Y\%m\%d).tar.gz /var/lib/jenkins
# 每周更新检查
0 3 * * 0 apt update && apt list --upgradable | grep jenkins
# 每月更换Webhook Token
0 4 1 * * /usr/local/bin/rotate-jenkins-secrets.sh
```
### 安全改进路线图
**Phase 1(当前):基础防护**
- ✅ 网络隔离
- ✅ HTTP Basic Auth
- ✅ Webhook签名验证
**Phase 2(1个月内):增强认证**
- 🔲 集成OAuth2/OIDC
- 🔲 多因素认证(MFA
- 🔲 细粒度权限控制
**Phase 3(3个月内):高级防护**
- 🔲 Web应用防火墙(WAF
- 🔲 入侵检测系统(IDS
- 🔲 安全信息和事件管理(SIEM
**Phase 4(6个月内):零信任架构**
- 🔲 零信任网络访问(ZTNA
- 🔲 微服务隔离
- 🔲 持续安全验证
---
## 📞 联系方式
**安全负责人:** 张翔
**应急响应:** security@your-domain.com
**技术支持:** devops@your-domain.com
---
## 📚 参考资料
- [Jenkins Security Best Practices](https://www.jenkins.io/doc/book/security/)
- [OWASP CI/CD Security Guide](https://owasp.org/www-project-devsecops-guideline/)
- [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
- [Jenkins Security Advisory](https://www.jenkins.io/security/advisories/)
---
**最后更新:** 2026-04-07
**文档版本:** 1.0