故障排查报告:GitLab 18.11.3 后台 Settings 500

一、问题背景

GitLab 版本:

GitLab 18.11.3 FOSS
Ruby 3.3.10
PostgreSQL 17.8
GitLab Shell 14.49.0

部署方式:

  • Omnibus GitLab
  • 外层 Nginx 反向代理
  • HTTPS 终止于 Nginx

初始目标:

禁止匿名用户访问 /explore

在后台关闭:

css 复制代码
Admin → Settings → General → Visibility and access controls

时,点击 Save 出现:

vbscript 复制代码
500 Internal Server Error

但:

  • GitLab Web 正常
  • Clone 正常
  • Push 正常
  • CI 基本正常

只有后台保存配置时 500。

二、现象与初步判断

浏览器 F12:

bash 复制代码
POST /admin/application_settings/general 500

同时发现:

css 复制代码
Mixed Content favicon warning

但后续确认:Mixed Content 不是根因。

三、日志分析

Rails 日志出现:

arduino 复制代码
OpenSSL::Cipher::CipherError

以及:

bash 复制代码
lib/authn/token_field/encryption_helper.rb
token_authenticatable
ensure_token
decrypt_token

说明:GitLab 在读取某个 encrypted token 时解密失败。

四、排查过程

1. 初步怀疑 Project visibility

测试:

less 复制代码
p = Project.find_by(name: "gaotong")
p.save!

结果:

ruby 复制代码
=> true

说明:

  • Project Model 正常
  • 普通 save 正常

2. 批量扫描 Project

执行:

ruby 复制代码
Project.find_each do |p|
  begin
    p.save!
  rescue => e
    puts p.id
    puts e
  end
end

发现:

大量项目出现:

arduino 复制代码
OpenSSL::Cipher::CipherError

初步确认:

GitLab 存在大量历史损坏 token。

3. 使用 secrets doctor

执行:

复制代码
gitlab-rake gitlab:doctor:secrets

结果:

css 复制代码
Total: 185 row(s) affected

包括:

DeployToken 148
RemoteMirror 19
ProjectImportData 10
User 3
Ci::Build 3
ApplicationSetting 1

说明:实例存在大规模 encrypted state 损坏。

五、核心问题定位

最终定位:

复制代码
ApplicationSetting.current.error_tracking_access_token

触发:

arduino 复制代码
OpenSSL::Cipher::CipherError

说明:后台 Settings 页面在保存时会读取 error_tracking_access_token。而该 token 已无法解密。

六、数据库验证

PostgreSQL 中确认字段:

sql 复制代码
SELECT column_name
FROM information_schema.columns
WHERE table_name='application_settings'
AND column_name LIKE '%error_tracking%';

结果:

复制代码
error_tracking_access_token_encrypted

执行:

ini 复制代码
UPDATE application_settings
SET error_tracking_access_token_encrypted = NULL;

验证:

sql 复制代码
SELECT
  error_tracking_access_token_encrypted IS NULL
FROM application_settings;

结果:

复制代码
t

说明:数据库字段已经成功清空。

七、异常现象

即使数据库字段已 NULL:

复制代码
s.error_tracking_access_token

仍继续触发:

复制代码
decrypt_token
ensure_token
token_set?

并报:

arduino 复制代码
OpenSSL::Cipher::CipherError

说明:GitLab 18.11 token_authenticatable 内部状态已异常。

疑似:

  • token framework bug
  • cached token state
  • 历史 encrypted metadata 残留
  • secrets 与 token state 不一致

八、临时验证

通过 monkey patch:

ruby 复制代码
ApplicationSetting.class_eval do
  define_method(:error_tracking_access_token) do
    nil
  end
end

成功绕过 getter。

说明:500 的核心触发点就是该 token getter。

九、最终工程决策

由于:

  • GitLab 主功能正常
  • 问题深入 token framework 内核
  • 修复成本远高于收益
  • 真实目标只是"禁止匿名访问"

最终决定:在 Nginx 层直接 deny。

配置:

bash 复制代码
location ~ ^/(explore|public|users/sign_up) {
    return 302 /users/sign_in;
}

避免继续深入 GitLab 内部 token 状态修复。

十、结论

本次问题本质属于:

GitLab 历史 encrypted state / secrets 不一致导致的 token framework 异常。

特点:

  • 系统大部分功能正常
  • 后台部分设置页 500
  • 仅在触发 token getter 时异常
  • 普通运维层难以彻底修复

十一、经验总结

1. GitLab 后台 500 首先检查:

复制代码
gitlab-rake gitlab:doctor:secrets

2. GitLab 17/18 后:

复制代码
token_authenticatable

是高风险区域。

3. secrets.json 不一致会导致:

  • token 解密失败
  • 后台 save 500
  • 部分 API 异常

但:系统表面仍可能正常运行。

4. 对于"匿名访问控制"类需求:

Nginx / WAF / Reverse Proxy 收口通常比深入修 GitLab 更稳。

相关推荐
Mike_6662 天前
git@gitlab-rdc.xxxxx.com: Permission denied (publickey).fatal: 无法读取远程仓库。
git·elasticsearch·gitlab
雨声不在4 天前
gitlab ci Runner 配置
gitlab·cicd
曾庆睿6 天前
【基于 RHEL 9.3 的 K8s + GitLab 全自动化部署环境搭建第一篇】
kubernetes·自动化·gitlab
曾庆睿6 天前
【基于 RHEL 9.3 的 K8s + GitLab 全自动化部署环境搭建第二篇】
kubernetes·自动化·gitlab
xmlhcxr10 天前
从 0 到 1 落地企业级 DevOps CI/CD 流水线:基于 GitLab+Jenkins+Harbor 的完整实践
运维·docker·gitlab·jenkins·harbor·devops
高旭的旭11 天前
GitLab Omnibus Docker 内存优化实战:从 4.7 GiB 降到 3.2 GiB
docker·容器·gitlab
牛奶咖啡1314 天前
Git实践——GitLab服务器的部署与使用
gitlab·gitlab是什么·gitlab有啥用·gitlab适用场景·gitlab的版本如何选·安装部署gitlab·gitlab的使用
lisanmengmeng15 天前
Gitlab搭建
gitlab