Skip to content

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

pre-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/admins

GitLab 分支保护

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 owners

CODEOWNERS

# .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:
  - 查看代码
  - 创建 Issues

GitLab 权限

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-log

GitLab 审计日志

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 使用中的安全风险,保护代码和敏感信息的安全。