17. 把密码提交进 Git?安全实践:密钥管理与审计日志

「Git」系列已发布: 00. 改崩代码不敢回退?Git 版本控制 3 分钟救你狗命 | 01. Git 装完不会配?Windows/macOS/Linux 三端配置一次到位 | 02. Git 配置总踩坑?全局/仓库/SSH 密钥一次搞懂 | 03. add/commit/push 别再死记:Git 工作流核心概念实操 | 04. Git 分支管理:5 步彻底搞懂 branch 与 merge | 05. clone/fetch/pull/push 分不清?Git 远程协作实战 | 06. 给版本打上永久印记:Git 标签管理与发布实战 | 07. 切分支怕丢改动?Git stash 暂存恢复保护现场 | 08. rebase 不是 merge 的替代品:Git 故事线重构进阶 | 09. Git 日志与调试:log/blame/diff 让历史无所遁形 | 10. 提交代码自动检查:Git Hooks 实战,质量不再靠人工 | 11. 多仓库依赖怎么管?Git 子模块统一版本一键更新 | 12. GitFlow vs GitHub Flow vs 主干:团队工作流 3 选 1 | 13. 仓库越来越大?Git LFS 让图片视频不再撑爆仓库 | 14. 合并冲突不是噩梦:Git 合并策略与冲突解决 | 15. 常用命令记不住?Git 别名让操作变成快捷键 | 16. 仓库太大会卡顿?git gc + bfg 清理历史垃圾实战 | 17. 把密码提交进 Git?安全实践:密钥管理与审计日志(本文)

密钥进仓库等于把家门钥匙挂门口。.gitignore、secret 扫描、pre-commit 钩子、审计日志——一套 Git 安全实践堵死泄露口。

配置详解(第 02 篇)和远程仓库操作(第 05 篇)要熟。需要装 GPG(GnuPG)做提交签名验证。

一、提交签名

1.1 GPG 签名的意义

Git 的提交者信息(name + email)随便填——没有任何机制阻止伪造:

git config user.name "Linus Torvalds"
git config user.email "torvalds@linux-foundation.org"
git commit -m "fake commit"

签名通过非对称加密验证提交真实性——只有持有私钥的人才能生成有效签名。

1.1.1 生成 GPG 密钥


# 装 GPG

# macOS: brew install gnupg

# Ubuntu: sudo apt install gnupg2

# 生成密钥对

gpg --full-generate-key

# 交互选择:

# 密钥类型:RSA and RSA(默认)

# 密钥长度:4096

# 有效期:2y

# 姓名:和 Git 的 user.name 一致

# 邮箱:和 Git 的 user.email 一致

# 示例输出:

# pub   rsa4096 2024-01-01 [SC] [expires: 2026-01-01]

# ABCDEF1234567890ABCDEF1234567890ABCDEF12

# uid   Zhang San <zhangsan@example.com>

# sub   rsa4096 2024-01-01 [E] [expires: 2026-01-01]

1.1.2 配置 Git 签名


# 列出密钥

gpg --list-secret-keys --keyid-format=long

# 拿到密钥 ID(sec 行后的 16 位十六进制)

# sec   rsa4096/ABCDEF1234567890 2024-01-01

# 配置 Git 用这个密钥

git config --global user.signingkey ABCDEF1234567890

# 所有提交自动签名

git config --global commit.gpgsign true

# 所有标签自动签名

git config --global tag.gpgsign true

1.1.3 日常操作


# 带签名提交

git commit -S -m "feat: 实现用户认证模块"

# 带签名标签

git tag -s v1.0.0 -m "v1.0.0 正式发布"

# 验证提交签名

git verify-commit HEAD

# 验证标签签名

git verify-tag v1.0.0

# 看签名状态

git log --show-signature -5

1.1.4 上传公钥到 GitLab


# 导出公钥

gpg --armor --export ABCDEF1234567890

# 粘贴到 GitLab → 用户设置 → GPG Keys → 添加密钥

验证后会显示 “Verified” 徽章。

1.2 敏感信息保护

本节围绕 敏感信息保护 进行介绍,说明它的核心概念、常见使用场景以及在实际操作中需要注意的要点,帮助读者快速掌握该功能的作用并安全地落地。

1.2.1 检测已提交的敏感信息


# git-secrets(AWS 开源)

brew install git-secrets
git secrets --install
git secrets --register-aws

# 扫当前仓库

git secrets --scan-history

# 自定义规则

git secrets --add 'API[_-]?KEY\s*[:=]\s*[A-Za-z0-9+/]{20,}'
git secrets --add '-----BEGIN RSA PRIVATE KEY-----'

# Gitleaks(更全面)

brew install gitleaks
gitleaks detect --source . --verbose
gitleaks detect --source . --report-path gitleaks-report.json

1.2.2 从历史中移除敏感信息


# 用 BFG(见第 16 篇)

# 建要替换的文本文件

echo "AKIAIOSFODNN7EXAMPLE" >> sensitive.txt
echo "password: production123" >> sensitive.txt

# 执行替换

java -jar bfg.jar --replace-text sensitive.txt my-repo.git

# 或用 filter-repo

git filter-repo --path passwords.txt --invert-paths

# 替换后强制推送(团队协调好)

git push origin --force --all
git push origin --force --tags

1.2.3 预防措施


# .git/hooks/pre-commit

#!/bin/bash

# 拦截疑似密钥的提交

PATTERNS=(
"AKIA[0-9A-Z]{16}"           # AWS Access Key
"sk-[a-zA-Z0-9]{32}"          # Stripe Secret Key
"ghp_[a-zA-Z0-9]{36}"         # GitHub Personal Access Token
"glpat-[a-zA-Z0-9\-]{20,}"    # GitLab Personal Access Token
"-----BEGIN RSA PRIVATE KEY"
"-----BEGIN OPENSSH PRIVATE KEY"
)
for pattern in "${PATTERNS[@]}"; do
if git diff --cached --name-only | xargs grep -lE "$pattern" 2>/dev/null; then
echo "============================================"
echo "警告:检测到疑似敏感信息"
echo "请确认是否确实需要提交这些凭据"
echo "============================================"
exit 1
fi
done
exit 0

1.3 访问控制

本节围绕 访问控制 进行介绍,说明它的核心概念、常见使用场景以及在实际操作中需要注意的要点,帮助读者快速掌握该功能的作用并安全地落地。

1.3.1 分支保护

在 GitLab 配置:

项目 → Settings → Repository → Protected Branches
main 分支:

- Allowed to merge: Maintainers only
- Allowed to push: No one
- Require approval: 2 approvers
- Code owner approval: Required
develop 分支:

- Allowed to merge: Maintainers + Developers
- Allowed to push: No one

1.3.2 推送规则(GitLab Premium/Ultimate)

Push Rules 可以在项目级阻止不合规推送——限制提交者邮箱格式、提交信息必须含 JIRA 编号、分支命名规范、文件大小上限、禁止特定扩展名。

1.3.3 签名策略强制执行


# .gitlab-ci.yml

verify-commits:
  stage: .pre
  script:

    - |
  for commit in $(git rev-list origin/main..HEAD); do
  if ! git verify-commit $commit 2>/dev/null; then
  echo "错误:$commit 未签名或签名无效"
  exit 1
  fi
  done
  rules:

    - if: $CI_MERGE_REQUEST_ID

1.4 仓库安全审计

本节围绕 仓库安全审计 进行介绍,说明它的核心概念、常见使用场景以及在实际操作中需要注意的要点,帮助读者快速掌握该功能的作用并安全地落地。

1.4.1 审计日志

GitLab 提供完整审计日志(Admin Area → Monitoring → Audit Events),可追踪:

  • 用户登录/登出
  • 项目创建/删除/可见性变更
  • 成员权限变更
  • Merge Request 合并/关闭
  • 分支保护规则变更
  • CI/CD 变量修改

1.4.2 定期安全扫描


# 自动化审计脚本

#!/bin/bash

# audit-gitlab.sh

GITLAB_URL="(gitlab.example.com)"
TOKEN="$GITLAB_API_TOKEN"

# 列出所有公开项目(潜在泄露)

curl -s --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/projects?visibility=public&per_page=100" | \
jq '.[] | {name: .name, visibility: .visibility, last_activity: .last_activity_at}'

# 检查无保护分支的项目

curl -s --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/projects?per_page=100" | \
jq -r '.[] | select(.archived == false) | .id' | \
while read project_id; do
protected=$(curl -s --header "PRIVATE-TOKEN: $TOKEN" \
"$GITLAB_URL/api/v4/projects/$project_id/protected_branches" | jq 'length')
if [ "$protected" -eq 0 ]; then
echo "项目 $project_id 没有保护分支"
fi
done

1.5 SSH 签名(Git 2.34+)

除了 GPG,Git 2.34+ 也能用 SSH 密钥签名:


# 配置 SSH 签名

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub

# 允许的签名者

git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers

# ~/.ssh/allowed_signers 格式:

# zhangsan@example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...

# 验证 SSH 签名

git verify-commit HEAD

1.6 文章引用

📌 本文首发于微信公众号 【运维知识点滴】——专注运维实战干货,微信搜索“运维知识点滴”或扫下方二维码关注,更新不迷路。

微信公众号【运维知识点滴】 微信小程序【A5单据合并&大试卷拆分转A4打印】
运维实战干货 · 关注追更 Word 转 PDF · 试卷/发票打印神器 · 免费
运维实战干货 · 关注追更 Word 转 PDF · 试卷/发票打印神器 · 免费

💡 小程序【A5单据合并&大试卷拆分转A4打印】是干嘛的? 一个 Word 转 PDF 的打印神器,专治“文档版式和打印机对不上”:

  • A3 试卷打不出来? 学校发的电子版试卷多是 A3,家用打印机只吃 A4——上传 Word 一键转换:可缩到一页 A4(页数不变),也可对半拆成两张 A4(1:1 原大、字更清晰),两种模式自选;
  • 版式不乱:真实渲染引擎原样转换、绝不重排内容,转出的 PDF 和原 Word 排版一致,公式/表格/图片不跑版;
  • 两张 A5 单据拼一张 A4:出租车票、火车票等报销凭证拼版后,一次打印、整齐粘贴;
  • 隐私省心:无需注册,转换结果留存 5 天、最多下载 5 次即自动删除,不留任何历史记录;
  • 微信扫码即用,免费、免安装,支持 doc / docx(≤50MB)。

上一篇:16. 仓库太大会卡顿?git gc + bfg 清理历史垃圾实战