Appearance
Git 安全最佳实践
概述
Git 安全是软件开发中不可忽视的重要环节。敏感信息泄露、未授权访问、代码篡改等安全问题可能导致严重后果。本指南将介绍 Git 安全的最佳实践,包括敏感信息处理、SSH 密钥管理、访问控制和安全审计。
敏感信息处理
常见敏感信息
yaml
敏感信息类型:
- API 密钥和令牌
- 数据库密码
- SSH 私钥
- 加密密钥
- 用户个人信息
- 服务器配置
- 第三方服务凭证防止提交敏感信息
.gitignore 配置
gitignore
# 环境变量文件
.env
.env.local
.env.*.local
# 配置文件
config/secrets.yml
config/database.yml
config/credentials.yml
# 密钥文件
*.pem
*.key
*.p12
*.pfx
# IDE 配置
.idea/
.vscode/
*.swp
*.swo
# 系统文件
.DS_Store
Thumbs.db
# 日志文件
*.log
logs/
# 依赖目录
node_modules/
vendor/Git Secrets
bash
# 安装 git-secrets
# macOS
brew install git-secrets
# Ubuntu
sudo apt-get install git-secrets
# 初始化
git secrets --install
# 添加禁止模式
git secrets --register-aws
git secrets --add 'password\s*=\s*["\'].*["\']'
git secrets --add 'api_key\s*=\s*["\'].*["\']'
git secrets --add 'secret\s*=\s*["\'].*["\']'
# 扫描历史记录
git secrets --scan-history
# 扫描特定文件
git secrets --scan /path/to/filepre-commit Hook
bash
#!/bin/bash
# .git/hooks/pre-commit
# 检查敏感信息
if git rev-parse --verify HEAD >/dev/null 2>&1; then
against=HEAD
else
against=$(git hash-object -t tree /dev/null)
fi
# 检查的模式
PATTERNS=(
"password\s*=\s*['\"][^'\"]+['\"]"
"api_key\s*=\s*['\"][^'\"]+['\"]"
"secret\s*=\s*['\"][^'\"]+['\"]"
"token\s*=\s*['\"][^'\"]+['\"]"
"-----BEGIN.*PRIVATE KEY-----"
)
# 扫描暂存文件
FILES=$(git diff --cached --name-only)
for FILE in $FILES; do
if [ -f "$FILE" ]; then
for PATTERN in "${PATTERNS[@]}"; do
if grep -E "$PATTERN" "$FILE" > /dev/null 2>&1; then
echo "错误: 发现敏感信息在 $FILE"
echo "模式: $PATTERN"
exit 1
fi
done
fi
done
exit 0清理已提交的敏感信息
使用 git filter-branch
bash
# 删除敏感文件
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch config/secrets.yml' \
--prune-empty --tag-name-filter cat -- --all
# 强制推送
git push origin --force --all
git push origin --force --tags使用 BFG Repo-Cleaner
bash
# 安装 BFG
brew install bfg
# 删除敏感文件
bfg --delete-files config/secrets.yml
# 替换敏感文本
bfg --replace-text passwords.txt
# 清理历史
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# 强制推送
git push origin --force使用 git-filter-repo
bash
# 安装
pip install git-filter-repo
# 删除文件
git filter-repo --path config/secrets.yml --invert-paths
# 替换文本
git filter-repo --replace-text expressions.txt
# 清理
git reflog expire --expire=now --all
git gc --prune=now --aggressive环境变量管理
使用 .env 文件
bash
# .env (不提交到 Git)
DATABASE_URL=postgresql://localhost/mydb
API_KEY=your-api-key
SECRET_KEY=your-secret-key
# .env.example (提交到 Git)
DATABASE_URL=postgresql://localhost/database_name
API_KEY=your_api_key_here
SECRET_KEY=your_secret_key_here使用配置管理工具
javascript
// config.js
module.exports = {
database: {
url: process.env.DATABASE_URL || 'postgresql://localhost/dev',
},
api: {
key: process.env.API_KEY,
},
secret: process.env.SECRET_KEY,
};SSH 密钥管理
生成 SSH 密钥
bash
# 生成 ED25519 密钥(推荐)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 生成 RSA 密钥
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 指定文件名
ssh-keygen -t ed25519 -f ~/.ssh/github_key -C "your_email@example.com"
# 添加密码保护
# 在提示时输入密码配置 SSH
bash
# 编辑 SSH 配置
vim ~/.ssh/config
# 添加配置
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github_key
IdentitiesOnly yes
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/gitlab_key
IdentitiesOnly yes
Host company-gitlab
HostName gitlab.company.com
User git
IdentityFile ~/.ssh/company_key
IdentitiesOnly yes添加密钥到服务
bash
# 复制公钥
cat ~/.ssh/github_key.pub
# 或使用命令复制到剪贴板
# macOS
pbcopy < ~/.ssh/github_key.pub
# Linux
xclip -sel clip < ~/.ssh/github_key.pub
# Windows
clip < ~/.ssh/github_key.pub
# 添加到 GitHub/GitLab
# Settings -> SSH and GPG keys -> New SSH key管理 SSH Agent
bash
# 启动 SSH Agent
eval "$(ssh-agent -s)"
# 添加密钥
ssh-add ~/.ssh/github_key
# 列出已添加的密钥
ssh-add -l
# 删除所有密钥
ssh-add -D
# macOS 自动添加密钥
# 编辑 ~/.ssh/config
Host *
AddKeysToAgent yes
UseKeychain yes密钥轮换
bash
# 定期更换密钥(建议每年)
# 1. 生成新密钥
ssh-keygen -t ed25519 -f ~/.ssh/github_key_new
# 2. 添加到服务
cat ~/.ssh/github_key_new.pub
# 3. 更新配置
vim ~/.ssh/config
# 更新 IdentityFile
# 4. 测试新密钥
ssh -T git@github.com
# 5. 删除旧密钥
rm ~/.ssh/github_key
rm ~/.ssh/github_key.pub访问控制
分支保护
GitHub 分支保护
yaml
# Settings -> Branches -> Add rule
Branch name pattern: main
Rules:
☑ Require a pull request before merging
☑ Require approvals: 2
☑ Dismiss stale pull request approvals
☑ Require review from Code Owners
☑ Require status checks to pass before merging
☑ Require branches to be up to date
Status checks:
- ci/build
- ci/test
- security/scan
☑ Require signed commits
☑ Include administrators
☑ Restrict who can push
Users/Teams: @org/adminsGitLab 分支保护
yaml
# Settings -> Repository -> Protected branches
Branch: main
Allowed to merge:
- Maintainers
Allowed to push:
- No one
Allowed to force push:
- Disabled
Code owner approval:
☑ Require approval from code ownersCODEOWNERS
# .github/CODEOWNERS
# 默认所有者
* @org/admins
# 敏感代码
/config/ @org/security-team
/scripts/ @org/devops-team
# 核心代码
/src/core/ @org/senior-devs
/src/auth/ @org/auth-team
# 基础设施
/infrastructure/ @org/devops-team
Dockerfile @org/devops-team
docker-compose.yml @org/devops-team
# 安全相关
**/security* @org/security-team
**/auth* @org/auth-team权限管理
GitHub 权限
yaml
# Organization 权限级别
Owner:
- 完全管理权限
- 管理账单
- 添加/删除成员
Member:
- 创建仓库
- 查看组织信息
Outside Collaborator:
- 访问特定仓库
- 无组织权限
# Repository 权限级别
Admin:
- 完全控制权限
- 管理仓库设置
Maintain:
- 管理问题
- 合并 PR
- 管理发布
Write:
- 推送代码
- 管理 Issues
Read:
- 查看代码
- 创建 IssuesGitLab 权限
yaml
# Group 权限级别
Owner:
- 完全管理权限
- 管理成员
Maintainer:
- 管理项目
- 管理成员
Developer:
- 推送代码
- 创建 MR
Reporter:
- 查看代码
- 创建 Issue
Guest:
- 查看公开项目双因素认证
bash
# 启用 2FA
# GitHub
# Settings -> Account security -> Enable 2FA
# GitLab
# Settings -> Account -> Two-Factor Authentication
# 使用认证器应用
# - Google Authenticator
# - Authy
# - 1Password安全审计
审计日志
GitHub 审计日志
bash
# 查看审计日志
# Settings -> Security -> Audit log
# 使用 API
curl -H "Authorization: token YOUR_TOKEN" \
https://api.github.com/orgs/ORG/audit-logGitLab 审计日志
yaml
# Settings -> Monitoring -> Audit Events
Events:
- 用户登录
- 权限变更
- 仓库创建/删除
- 分支保护变更
- SSH 密钥添加/删除安全扫描
依赖扫描
yaml
# GitHub Dependabot
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10代码扫描
yaml
# GitHub CodeQL
# .github/workflows/codeql.yml
name: CodeQL
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: javascript
- name: Analyze
uses: github/codeql-action/analyze@v2密钥扫描
yaml
# GitLab Secret Detection
# .gitlab-ci.yml
include:
- template: Security/Secret-Detection.gitlab-ci.yml
secret_detection:
stage: test安全检查清单
markdown
## 定期安全检查
### 代码安全
- [ ] 无敏感信息提交
- [ ] 依赖无已知漏洞
- [ ] 代码无安全问题
- [ ] 输入验证完善
### 访问控制
- [ ] 分支保护已配置
- [ ] 权限分配合理
- [ ] CODEOWNERS 已配置
- [ ] 双因素认证已启用
### 密钥管理
- [ ] SSH 密钥已保护
- [ ] API 密钥定期轮换
- [ ] 密钥权限最小化
- [ ] 密钥存储安全
### 审计监控
- [ ] 审计日志已启用
- [ ] 异常行为监控
- [ ] 安全告警已配置
- [ ] 定期安全审计安全事件响应
密钥泄露处理
bash
# 1. 立即撤销泄露的密钥
# 在服务提供商处撤销
# 2. 生成新密钥
ssh-keygen -t ed25519 -f ~/.ssh/new_key
# 3. 清理 Git 历史
git filter-repo --path config/secrets.yml --invert-paths
# 4. 强制推送
git push origin --force --all
# 5. 通知相关人员
# 发送安全公告
# 6. 记录事件
# 更新安全日志未授权访问处理
bash
# 1. 锁定账户
# 暂时禁用相关账户
# 2. 检查审计日志
# 查看访问记录
# 3. 重置凭证
# 更改密码和密钥
# 4. 评估影响
# 检查数据是否泄露
# 5. 加强安全措施
# 启用更强的访问控制
# 6. 通知相关方
# 报告安全事件最佳实践总结
开发者安全实践
markdown
1. **敏感信息管理**
- 使用环境变量
- 配置 .gitignore
- 使用密钥管理服务
2. **密钥安全**
- 使用 ED25519 密钥
- 定期轮换密钥
- 保护私钥安全
3. **访问控制**
- 最小权限原则
- 启用双因素认证
- 定期审查权限
4. **安全意识**
- 参加安全培训
- 关注安全公告
- 及时更新依赖团队安全实践
markdown
1. **流程安全**
- 强制代码审查
- 分支保护规则
- 自动化安全检查
2. **工具支持**
- 使用安全扫描工具
- 配置审计日志
- 设置安全告警
3. **应急响应**
- 制定应急计划
- 定期演练
- 及时响应事件
4. **持续改进**
- 定期安全审计
- 更新安全策略
- 分享安全知识总结
Git 安全是一个持续的过程:
核心原则:
- 预防为主
- 最小权限
- 持续监控
- 快速响应
关键措施:
- 保护敏感信息
- 管理好密钥
- 控制访问权限
- 定期安全审计
通过遵循这些最佳实践,可以显著降低 Git 使用中的安全风险,保护代码和敏感信息的安全。
