服务公告

服务公告 > 综合新闻 > Git:Git安全加固

Git:Git安全加固

发布时间:2026-04-22 20:01

一、前言

搞过的人都知道,最烦的是代码库裸奔在外网,密码密钥当白菜扔在commit历史里,权限管理跟菜市场似的谁都能进谁都能推。有团队的GitLab账户跟离职员工账号一起飞,有commit直接把生产数据库密码给push上去的。我见过太多这种惨案。今天不废话,直接上Git安全加固的真实操作步骤。

二、操作步骤

第1步:检查Git版本并堵住已知漏洞

git --version

预期输出:

git version 2.39.2

如果版本低于2.39.3(当前LTS稳定版),立刻升级。Git历史漏洞列表自己去查CVE,重点关注remote code execution和credential exposure类的高危漏洞。

CentOS/RHEL:

sudo yum remove git -y sudo rpm -i https://packages.example.com/git-2.39.3-1.el7.x86_64.rpm

Ubuntu/Debian:

sudo apt update sudo apt install git -y sudo add-apt-repository ppa:git-core/ppa sudo apt update && sudo apt install git -y

第2步:全局锁定危险协议和URL重写

彻底禁用git://协议,这玩意儿走明文TCP,credential直接裸奔在网络上。

git config --global url."https://".insteadOf git:// git config --global url."https://github.com/".insteadOf git@github.com:

预期输出:

git:// git@github.com:

验证配置生效:

git config --global --get-regexp url

预期输出:

url.https://.insteadOf git:// url.https://github.com/.insteadOf git@github.com:

第3步:强制GPG签名提交

没签名验证的commit就是裸奔的身份证,谁都能冒名顶替。

gpg --list-keys

如果没GPG密钥,先生成:

gpg --full-generate-key # 选择RSA 4096-bit,密码用强密码,切勿用空密码

预期输出:

gpg: key 7A9C3D2E1F0B4A5C marked as ultimate trust. gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/XXXXXXX.rev' pub rsa4096 2024-01-15 [SC] 7A9C3D2E1F0B4A5C6D7E8F9A0B1C2D3E4F5A6B7C uid ultimate admin@example.com sub rsa4096 2024-01-15 [E]

导出公钥并配置Git使用:

gpg --armor --export admin@example.com | head -10

预期输出:

-----BEGIN PGP PUBLIC KEY BLOCK----- Comment: GPGTag marker mQINBGXXXXX ...
git config --global user.signingkey 7A9C3D2E1F0B4A5C6D7E8F9A0B1C2D3E4F5A6B7C git config --global commit.gpgsign true

从此每次commit都会弹出GPG签名提示,commit message会带一个verified标签。

第4步:清理Git历史中的敏感信息

⚠️ 警告:以下操作会重写仓库历史,团队协作情况下务必通知所有协作者!务必先备份仓库!

先安装BFG Repo-Cleaner(比git filter-branch快10倍不止):

wget https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar mv bfg-1.14.0.jar bfg.jar

清理所有包含密码/密钥/secret的历史记录:

java -jar bfg.jar --replace-text passwords.txt --replace-text secrets.txt --replace-text credentials.txt your-repo.git

预期输出:

Using repo : your-repo.git Found 23 commits Cleaning commits ... Deleted 47 files ... In total, 23 object ids were changed ...

passwords.txt内容示例(每行一个敏感词匹配模式):

YOUR_PASSWORD= DB_PASSWORD= api_secret= PRIVATE_KEY=

清理完后强制推送:

git reflog expire --expire=now --all && git gc --prune=now --aggressive

第5步:配置Git忽略敏感文件

新建仓库时就把敏感配置挡在门外,别等出事了再想起来加.gitignore。

cat >> .gitignore << 'EOF' # 配置文件和密钥 *.pem *.key *.p12 *.jks config/secrets.yml config/credentials.yml .env .env.* *.local # 数据库连接配置 config/database.yml config/initializers/database.yml # 日志和临时文件 *.log tmp/ vendor/bundle/ # IDE配置 .vscode/ .idea/ *.swp EOF

如果已经有commit历史的文件需要移除但不删除本地副本:

git rm --cached .env git rm --cached config/secrets.yml git commit -m "Remove sensitive files from tracking"

第6步:GitLab/Gitea仓库权限加固

以GitLab为例,企业版的功能比社区版多,但基础权限模型是一样的。

创建受保护分支,只允许特定角色合并:

# 通过GitLab API创建Protected Branch curl --header "PRIVATE-TOKEN: YOUR_GITLAB_TOKEN" --request POST --data "name=main&push_access_level=0&merge_access_level=30" https://gitlab.example.com/api/v4/projects/123/protected_branches/main

预期输出:

{ "name": "main", "push_access_levels": [{"access_level": 0}], "merge_access_levels": [{"access_level": 30}], "unprotect_access_levels": [{"access_level": 40}] }

说明:access_level 0 = No one, 30 = Maintainers, 40 = Owners

强制所有分支必须通过Merge Request:

# 设置MR必须成功才能合并 curl --header "PRIVATE-TOKEN: YOUR_GITLAB_TOKEN" --request POST --data "id=123&name=main&merge_requests_require_success_to_merge=true" https://gitlab.example.com/api/v4/projects/123/protected_branches/main

禁止直接push到受保护分支,所有代码必须经过MR+Code Review流程。

第7步:设置Git操作审计日志

GitLab EE版本有内置审计日志,社区版自己搭审计脚本。

# 查看最近的push事件 grep -E "POST|push|refs/heads" /var/log/gitlab/gitlab-rails/production.log | tail -50

预期输出:

POST /api/v4/projects/123/repository/commits User: admin@example.com Branch: main Message: "Update config" IP: 192.168.1.100 Timestamp: 2024-01-15T10:23:45Z

启用Git事件webhook通知到安全告警系统:

# 在GitLab Admin Area配置webhook # URL: https://your-siem.example.com/webhook/gitlab # Events: Push events, Merge request events, Member events

独立Git服务器用auditd记录所有git命令调用:

# CentOS/RHEL sudo auditctl -w /usr/bin/git -p x -k git_command # Ubuntu sudo auditctl -w /usr/bin/git -p x -k git_command
sudo aureport -k | grep git

预期输出:

2. 2024-01-15 10:23:45 git_command /usr/bin/git /home/repos/project 3. 2024-01-15 10:24:12 git_command /usr/bin/git /home/repos/project ...

第8步:配置SSH Key最小权限

# 生成ED25519密钥(比RSA更安全且更短) ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/gitlab_ed25519

预期输出:

Generating public/private ed25519 key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /usr/home/user/.ssh/gitlab_ed25519 Your public key has been saved in /usr/home/user/.ssh/gitlab_ed25519.pub

配置SSH客户端强制使用指定密钥和禁用密码登录:

cat >> ~/.ssh/config << 'EOF' Host gitlab.example.com HostName gitlab.example.com User git IdentityFile ~/.ssh/gitlab_ed25519 IdentitiesOnly yes PasswordAuthentication no PubkeyAuthentication yes Host github.com HostName github.com User git IdentityFile ~/.ssh/github_ed25519 IdentitiesOnly yes PasswordAuthentication no EOF chmod 600 ~/.ssh/config

三、常见问题FAQ

Q:之前已经push上去的密码怎么办?密码已经泄露了怎么救?

A:别想着靠Git加固能解决问题,这种情况下就一个字:改。立刻去改掉所有用过的密码,撤销所有可能相关的API Key,通知安全团队这是个P0事件。Git历史删不掉,就算你重写了历史,github/gitlab的缓存和 forks 都可能还存着老版本。去haveibeenpwned.com查你的邮箱有没有泄露记录。另外,如果密码对应的是数据库或生产环境密码,立刻启动应急预案,那套密码直接报废,别抱侥幸心理。

Q:团队成员觉得GPG签名太麻烦,都想禁用,怎么说服他们?

A:现实点讲,你要是团队负责人,直接在GitLab/Gitea那边强推protected branch + require signed commits,不签名的commit根本push不上去,谁都别想绕过。要是普通开发者的角色,那就拿具体案例说话——2019年GitLab被黑客利用弱凭证删除数据的事故自己百度去,告诉他们不签名就是在裸奔。你要是跟我吐槽说团队里的人都是老油条根本不管这套,那只能说明你们公司安全建设本来就没做好,先去找领导要授权。

Q:公司内网GitLab服务器,想省事不做HTTPS行不行?

A:行个屁,内网不等于安全。内网横向渗透了解一下?你们的DHCP服务器、DNS服务器、交换机management口被拿下过吗?代码仓库是核心资产,别拿"内网"当借口省掉TLS。省事的结果就是有一天某台员工笔记本中马,内网DNS被劫持,git pull的时候凭证直接被明文拿走。内网GitLab装自签名证书的成本是零,就一个命令的事情,别找借口。

Q:离职员工的账户和SSH Key怎么处理?

A:离职当天就要revoke GitLab账户和所有SSH Key,这是IT Ops的活,别拖。GitLab Admin Panel直接disable账号,同时检查这个人创建的所有Deploy Key和Personal Access Token,全部删除。另外review一遍这个人参与过的仓库,看有没有被加进不相关的项目。如果用的是自建的Gitea,同样的流程在Admin面板操作一遍。GitHub的话去enterprise settings批量处理。别跟我说你们没有统一管理,权限管理烂到这种程度出事只是时间问题。

四、总结

核心要点记住三条:

  1. 堵住传输层漏洞:禁用git://协议,强制HTTPS/SSH,GPG签名commit是基操。这些做不好,后面都是白搭。
  2. 清理历史敏感数据:BFG Repo-Cleaner定期跑,password、secret、credential全部从历史里清干净。清理完重写历史后记得通知所有协作者rebase。密码一旦泄露就当废掉,别侥幸。
  3. 权限管控和审计:受保护分支强推MR+Code Review流程,离职人员账户即时revoke,auditd记录所有git操作日志。权限管理不是一次性的,是持续运营的事。

延伸阅读:

上一篇: AutoGPT:安装配置

已经是最后一篇啦!