992 字
5 分钟
Gitleaks 基础使用 - 不要再广播密钥啦
从 Gitleaks 检查,到抹除某一行密钥内容,逐行教你如何在项目开源前确保脱敏
2026-02-25
2026-02-26

这是个什么?#

Gitleaks 是一个开源 SAST(静态应用安全测试)命令行工具,用于检测 Git 仓库以防止把密码、API 密钥和访问令牌等机密信息硬编码到代码中。

简单来说,就是防止你把密钥公之于众,然后被刷爆

如何安装#

Ubuntu/Debian#

APT 似乎没有 Gitleaks 的包,可以选择 下载 对应架构的二进制包,解压后直接运行即可(也可移至 /usr/local/bin 以便全局使用

NixOS#

I use NixOS, btw.

Nixpkgs 实在是一个伟大的发明,你只需要运行这行命令:

Terminal window
nix-shell -p gitleaks

就可以获得一个临时的,拥有 Gitleaks 软件包的 shell。当然也可以将其加入 systemPackages

Github Action#

顺带一提,官方提供了 Action ,可以直接关联仓库并检查(虽然我没用过)


如何使用#

Terminal window
gitleaks git . -v

该行命令会扫描当前目录下的 git 仓库,并提示可能的泄露 这里我建了一个临时的仓库来实验,并提交了一些commit,然后使用 gitleaks 检查:

测试结果

虽然 gitleaks 成功检测到了可能的泄露,但此时我们已经提交了很多commit, 一个个 revert 是有些不太现实的。当然,你可以选择直接吊销/轮换密钥。 这里假设密钥和账户强绑定,无法吊销;或者项目曾经是闭源的,没有在意这方面,那就需要强制修改 git 历史了。


强制修改 git 历史的方法#

注意

请小心谨慎地修改 git 历史,并在 git push 后确保在所有设备上拉取一遍以保证同步

git 原生方法#

常规修改#

如何泄露的影响还算不大,可以使用 Git 内置的交互式变基 (interactive rebase) 来逐个更改提交内容。 例如上图,需要变基到 2e8121e 才能修改之后的 d9df113

Terminal window
git rebase -i 2e8121e

变基操作界面

  1. 我们需要修改 d9df113,因此将第一行的”pick”改成”edit”并保存,开始交互式变基;
  2. 通过编辑器删除泄露的密钥;
  3. 执行 git add . 将更改提交到暂存区,执行 git status 手动二次确认;
  4. 确定修补完成后,执行 git commit --amend,在这里可以修改 commit 内容,也可以不修改,但必须手动保存一次文件;
  5. 这一轮修复就算成功了,执行 git rebase --continue,git将开始自动合并,直到出现冲突。

处理合并冲突#

遇到合并冲突时,使用 git status 查看,并打开冲突的文件:

❯ cat .env
<<<<<<< HEAD
=======
API_KEY=yAxfgL1GnYhk0UYXZdt2eADqnrNXezeK
TIME_ZONE=Asia/Shanghai
>>>>>>> 72fd120 (feat: 又实现了一个功能)

这些格式的意思是:

  • <<<<<<< HEAD======= 的部分:当前分支的内容(也就是修改后的)
  • =======>>>>>>> 72fd120 的部分:旧分支的内容(修改前)

此处需要删除API_KEY,因此将文件修改成:

TIME_ZONE=Asia/Shanghai

然后,git add .git commit --amendgit rebase --continue如此循环,直到变基全部完成

最终效果#

再次运行 gitleaks git . -v,就可以看到一片绿啦~~ 修复完成

然后 force push 就可以强制修改远端内容:

Terminal window
git push --force --all
git push --force --tags

git filter-branch 方法#

将某个文件从所有历史中移除#

先筛选并执行移除:

Terminal window
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch <文件路径>' \
--prune-empty --tag-name-filter cat -- --all

再清理备份引用,执行垃圾回收:

Terminal window
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now --aggressive

将文件中的某一部分从所有历史中移除#

在这里使用sed作为示例,可以让AI编写适合你的替换命令:

Terminal window
git filter-branch --force --tree-filter '
grep -rl "LEAKED_KEY_PART" . | while read -r f; do
sed -i "s/LEAKED_KEY_PART/REDACTED/g" "$f"
done
' --tag-name-filter cat -- --all
提示

这会在每个提交 checkout 一次,仓库大时将非常慢。 替换模式尽量写具体,避免误伤正常内容。

最后同样是 force push: 然后 force push 就可以强制修改远端内容:

Terminal window
git push --force --all
git push --force --tags
文章修订历史 (2 次)
查看变更记录
2026-02-27docs: 补充 git filter-branch 方法
1dfaeba
2026-02-26docs: gitleaks 的基础使用方法
ce6a936
Gitleaks 基础使用 - 不要再广播密钥啦
https://rinx.nz/posts/gitleaks/
作者
RinStel
发布于
2026-02-25
许可协议
CC BY-NC-SA 4.0