Files
novalon-website/scripts/security
张翔 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
..

Jenkins安全加固快速部署指南

作者: 张翔
日期: 2026-04-07
紧急程度: 🔴 立即执行


5分钟快速响应

情况紧急?立即执行以下命令

# 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分钟)

前置准备

# 1. 克隆或进入项目目录
cd /path/to/novalon-website

# 2. 检查当前状态
sudo netstat -tlnp | grep 8080
curl -I http://localhost:8080

步骤1:配置环境变量

# 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

# 方法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:运行安全加固脚本

# 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证书(如未配置)

# 使用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

# 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:验证安全配置

# 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/

# 测试4Webhook签名验证
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)

🔍 验证检查清单

执行以下命令确认所有配置正确:

# ✅ 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

解决:

chmod +x scripts/security/jenkins-security-hardening.sh
sudo ./scripts/security/jenkins-security-hardening.sh

Q2: Jenkins无法启动

问题: 修改监听地址后Jenkins无法启动

解决:

# 检查配置文件
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

解决:

# 检查Nginx版本
nginx -v

# 确保版本 >= 1.18
sudo apt update && sudo apt upgrade nginx

# 验证配置
sudo nginx -t

Q4: Webhook触发失败

问题: Webhook返回403

解决:

# 检查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无法登录

解决:

# 重新生成密码文件
sudo htpasswd -c /etc/nginx/conf.d/.jenkins-htpasswd admin

# 重启Nginx
sudo systemctl restart nginx

📊 安全监控

设置定时监控

# 添加到crontab
crontab -e
# 每小时检查异常访问
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

查看实时日志

# 监控访问日志
tail -f /var/log/nginx/jenkins-access.log

# 监控错误日志
tail -f /var/log/nginx/jenkins-error.log

# 监控Jenkins日志
sudo journalctl -u jenkins -f

🔄 回滚方案

如果出现问题,可以快速回滚:

# 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仅监听127.0.0.1:8080
  • 防火墙已阻止外部访问8080
  • Nginx反向代理正常工作
  • HTTP Basic Auth认证生效
  • Webhook签名验证通过
  • SSL证书有效
  • 所有日志正常记录
  • 监控脚本运行正常
  • 备份策略已配置
  • 团队成员已通知

最后更新: 2026-04-07
文档版本: 1.0