042f66499a
- 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)
372 lines
8.1 KiB
Markdown
372 lines
8.1 KiB
Markdown
# Jenkins安全加固快速部署指南
|
||
|
||
**作者:** 张翔
|
||
**日期:** 2026-04-07
|
||
**紧急程度:** 🔴 立即执行
|
||
|
||
---
|
||
|
||
## ⚡ 5分钟快速响应
|
||
|
||
### 情况紧急?立即执行以下命令
|
||
|
||
```bash
|
||
# 1. 阻止外部访问8080端口
|
||
sudo ufw deny 8080/tcp && sudo ufw --force reload
|
||
|
||
# 2. 修改Jenkins监听地址
|
||
sudo sed -i 's|httpPort=8080|httpPort=8080 --httpListenAddress=127.0.0.1|' /etc/default/jenkins
|
||
sudo systemctl restart jenkins
|
||
|
||
# 3. 验证
|
||
sudo netstat -tlnp | grep 8080
|
||
# 应显示:127.0.0.1:8080
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 完整部署流程(30分钟)
|
||
|
||
### 前置准备
|
||
|
||
```bash
|
||
# 1. 克隆或进入项目目录
|
||
cd /path/to/novalon-website
|
||
|
||
# 2. 检查当前状态
|
||
sudo netstat -tlnp | grep 8080
|
||
curl -I http://localhost:8080
|
||
```
|
||
|
||
### 步骤1:配置环境变量
|
||
|
||
```bash
|
||
# 1. 复制环境变量模板
|
||
cp scripts/security/.env.jenkins.example scripts/security/.env.jenkins.production
|
||
|
||
# 2. 编辑配置文件
|
||
vim scripts/security/.env.jenkins.production
|
||
|
||
# 3. 生成随机密钥
|
||
# Webhook Token
|
||
openssl rand -hex 32
|
||
# 将输出复制到 JENKINS_WEBHOOK_TOKEN
|
||
|
||
# Webhook Secret
|
||
openssl rand -hex 32
|
||
# 将输出复制到 WEBHOOK_SECRET
|
||
|
||
# 管理员密码
|
||
openssl rand -base64 32
|
||
# 将输出复制到 JENKINS_ADMIN_PASSWORD
|
||
```
|
||
|
||
### 步骤2:配置Jenkins Credentials
|
||
|
||
```bash
|
||
# 方法1:通过Jenkins UI
|
||
# 访问:https://your-domain.com/jenkins/credentials/store/system/domain/_/
|
||
# 添加Secret text:
|
||
# ID: jenkins-webhook-token
|
||
# Secret: [步骤1生成的token]
|
||
|
||
# 方法2:通过Jenkins CLI
|
||
java -jar jenkins-cli.jar -s http://localhost:8080/ create-credentials-by-xml system::system::jenkins << EOF
|
||
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
|
||
<scope>GLOBAL</scope>
|
||
<id>jenkins-webhook-token</id>
|
||
<description>Jenkins Webhook Token</description>
|
||
<username></username>
|
||
<password>${JENKINS_WEBHOOK_TOKEN}</password>
|
||
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
|
||
EOF
|
||
```
|
||
|
||
### 步骤3:运行安全加固脚本
|
||
|
||
```bash
|
||
# 1. 设置权限
|
||
chmod +x scripts/security/jenkins-security-hardening.sh
|
||
|
||
# 2. 加载环境变量
|
||
export $(cat scripts/security/.env.jenkins.production | xargs)
|
||
|
||
# 3. 运行脚本
|
||
sudo -E ./scripts/security/jenkins-security-hardening.sh
|
||
|
||
# 按照提示输入:
|
||
# - 管理员密码
|
||
# - 是否立即重启服务
|
||
```
|
||
|
||
### 步骤4:配置SSL证书(如未配置)
|
||
|
||
```bash
|
||
# 使用Let's Encrypt
|
||
sudo apt install certbot python3-certbot-nginx
|
||
sudo certbot --nginx -d your-domain.com
|
||
|
||
# 或使用已有证书
|
||
sudo mkdir -p /etc/letsencrypt/live/your-domain.com
|
||
sudo cp your-cert.pem /etc/letsencrypt/live/your-domain.com/fullchain.pem
|
||
sudo cp your-key.pem /etc/letsencrypt/live/your-domain.com/privkey.pem
|
||
```
|
||
|
||
### 步骤5:配置Gitea Webhook
|
||
|
||
```bash
|
||
# 1. 进入Gitea仓库设置
|
||
# Settings -> Webhooks -> Add Webhook
|
||
|
||
# 2. 配置Webhook
|
||
# 目标URL: https://your-domain.com/generic-webhook-trigger/invoke
|
||
# HTTP方法: POST
|
||
# 触发条件: Push events
|
||
# 启用签名验证: 是
|
||
# 签名密钥: [步骤1生成的WEBHOOK_SECRET]
|
||
|
||
# 3. 测试Webhook
|
||
# 点击"Test Delivery"按钮
|
||
```
|
||
|
||
### 步骤6:验证安全配置
|
||
|
||
```bash
|
||
# 1. 运行自动验证
|
||
sudo /usr/local/bin/verify-jenkins-security.sh
|
||
|
||
# 2. 手动测试
|
||
# 测试1:直接访问8080端口(应失败)
|
||
curl -I http://YOUR_SERVER_IP:8080
|
||
|
||
# 测试2:匿名访问(应返回401)
|
||
curl -I https://your-domain.com/jenkins/
|
||
|
||
# 测试3:认证访问(应成功)
|
||
curl -I -u admin:YOUR_PASSWORD https://your-domain.com/jenkins/
|
||
|
||
# 测试4:Webhook签名验证
|
||
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"
|
||
```
|
||
|
||
---
|
||
|
||
## 📁 文件清单
|
||
|
||
```
|
||
scripts/security/
|
||
├── jenkins-security-hardening.sh # 主加固脚本
|
||
├── .env.jenkins.example # 环境变量模板
|
||
└── README.md # 本文档
|
||
|
||
docs/security/
|
||
└── JENKINS_SECURITY_HARDENING_GUIDE.md # 详细安全指南
|
||
|
||
Jenkinsfile # 已更新(移除硬编码token)
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 验证检查清单
|
||
|
||
执行以下命令确认所有配置正确:
|
||
|
||
```bash
|
||
# ✅ Jenkins仅监听127.0.0.1
|
||
sudo netstat -tlnp | grep 8080
|
||
# 预期:127.0.0.1:8080
|
||
|
||
# ✅ 防火墙已阻止8080
|
||
sudo ufw status | grep 8080
|
||
# 预期:8080/tcp DENY
|
||
|
||
# ✅ Nginx配置正确
|
||
sudo nginx -t
|
||
# 预期:test is successful
|
||
|
||
# ✅ HTTP Basic Auth已配置
|
||
ls -la /etc/nginx/conf.d/.jenkins-htpasswd
|
||
# 预期:文件存在且权限为600
|
||
|
||
# ✅ Jenkinsfile无硬编码token
|
||
grep -r "token.*=.*['\"].*['\"]" Jenkinsfile
|
||
# 预期:无输出
|
||
|
||
# ✅ SSL证书有效
|
||
openssl s_client -connect your-domain.com:443 -servername your-domain.com 2>/dev/null | openssl x509 -noout -dates
|
||
# 预期:显示证书有效期
|
||
|
||
# ✅ 服务运行正常
|
||
sudo systemctl status jenkins nginx
|
||
# 预期:active (running)
|
||
```
|
||
|
||
---
|
||
|
||
## 🚨 常见问题
|
||
|
||
### Q1: 脚本执行失败
|
||
|
||
**问题:** `permission denied`
|
||
|
||
**解决:**
|
||
```bash
|
||
chmod +x scripts/security/jenkins-security-hardening.sh
|
||
sudo ./scripts/security/jenkins-security-hardening.sh
|
||
```
|
||
|
||
### Q2: Jenkins无法启动
|
||
|
||
**问题:** 修改监听地址后Jenkins无法启动
|
||
|
||
**解决:**
|
||
```bash
|
||
# 检查配置文件
|
||
cat /etc/default/jenkins | grep JENKINS_ARGS
|
||
|
||
# 恢复备份
|
||
sudo cp /tmp/jenkins-security-backup-*/jenkins-default.bak /etc/default/jenkins
|
||
sudo systemctl restart jenkins
|
||
```
|
||
|
||
### Q3: Nginx配置错误
|
||
|
||
**问题:** `nginx: [emerg] unknown directive`
|
||
|
||
**解决:**
|
||
```bash
|
||
# 检查Nginx版本
|
||
nginx -v
|
||
|
||
# 确保版本 >= 1.18
|
||
sudo apt update && sudo apt upgrade nginx
|
||
|
||
# 验证配置
|
||
sudo nginx -t
|
||
```
|
||
|
||
### Q4: Webhook触发失败
|
||
|
||
**问题:** Webhook返回403
|
||
|
||
**解决:**
|
||
```bash
|
||
# 检查IP白名单
|
||
grep "allow" /etc/nginx/conf.d/jenkins-security.conf
|
||
|
||
# 检查签名验证
|
||
# 确保Gitea配置的签名密钥与WEBHOOK_SECRET一致
|
||
|
||
# 查看Nginx错误日志
|
||
tail -f /var/log/nginx/jenkins-error.log
|
||
```
|
||
|
||
### Q5: 认证失败
|
||
|
||
**问题:** HTTP Basic Auth无法登录
|
||
|
||
**解决:**
|
||
```bash
|
||
# 重新生成密码文件
|
||
sudo htpasswd -c /etc/nginx/conf.d/.jenkins-htpasswd admin
|
||
|
||
# 重启Nginx
|
||
sudo systemctl restart nginx
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 安全监控
|
||
|
||
### 设置定时监控
|
||
|
||
```bash
|
||
# 添加到crontab
|
||
crontab -e
|
||
```
|
||
|
||
```cron
|
||
# 每小时检查异常访问
|
||
0 * * * * /usr/local/bin/monitor-jenkins-security.sh >> /var/log/jenkins-security-monitor.log 2>&1
|
||
|
||
# 每天备份配置
|
||
0 2 * * * tar -czf /backup/jenkins-config-$(date +\%Y\%m\%d).tar.gz /var/lib/jenkins
|
||
|
||
# 每周发送安全报告
|
||
0 9 * * 1 /usr/local/bin/jenkins-security-report.sh | mail -s "Jenkins Security Report" admin@your-domain.com
|
||
```
|
||
|
||
### 查看实时日志
|
||
|
||
```bash
|
||
# 监控访问日志
|
||
tail -f /var/log/nginx/jenkins-access.log
|
||
|
||
# 监控错误日志
|
||
tail -f /var/log/nginx/jenkins-error.log
|
||
|
||
# 监控Jenkins日志
|
||
sudo journalctl -u jenkins -f
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 回滚方案
|
||
|
||
如果出现问题,可以快速回滚:
|
||
|
||
```bash
|
||
# 1. 恢复Jenkins配置
|
||
sudo cp /tmp/jenkins-security-backup-*/jenkins-default.bak /etc/default/jenkins
|
||
|
||
# 2. 恢复Nginx配置
|
||
sudo rm /etc/nginx/conf.d/jenkins-security.conf
|
||
sudo cp -r /tmp/jenkins-security-backup-*/nginx-conf/* /etc/nginx/conf.d/
|
||
|
||
# 3. 重启服务
|
||
sudo systemctl restart jenkins nginx
|
||
|
||
# 4. 恢复防火墙规则
|
||
sudo ufw allow 8080/tcp
|
||
sudo ufw --force reload
|
||
```
|
||
|
||
---
|
||
|
||
## 📞 获取帮助
|
||
|
||
**文档:**
|
||
- [完整安全指南](./JENKINS_SECURITY_HARDENING_GUIDE.md)
|
||
- [Jenkins官方安全文档](https://www.jenkins.io/doc/book/security/)
|
||
|
||
**应急联系:**
|
||
- 安全负责人:张翔
|
||
- 技术支持:devops@your-domain.com
|
||
|
||
---
|
||
|
||
## ✅ 部署后确认
|
||
|
||
完成所有步骤后,确认以下事项:
|
||
|
||
- [ ] Jenkins仅监听127.0.0.1:8080
|
||
- [ ] 防火墙已阻止外部访问8080
|
||
- [ ] Nginx反向代理正常工作
|
||
- [ ] HTTP Basic Auth认证生效
|
||
- [ ] Webhook签名验证通过
|
||
- [ ] SSL证书有效
|
||
- [ ] 所有日志正常记录
|
||
- [ ] 监控脚本运行正常
|
||
- [ ] 备份策略已配置
|
||
- [ ] 团队成员已通知
|
||
|
||
---
|
||
|
||
**最后更新:** 2026-04-07
|
||
**文档版本:** 1.0
|