故障排查报告: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 更稳。

相关推荐
霸道流氓气质11 天前
GitLab CI/CD 完全指南
linux·ci/cd·gitlab
sbjdhjd11 天前
从零搭建企业级 CI/CD(下):Jenkins+GitLab+Harbor 全链路实战指南
git·servlet·ci/cd·云原生·云计算·gitlab·jenkins
用什么都重名12 天前
Git 合并两个无共同历史的分支:从报错到解决全记录
git·gitlab
master33612 天前
GitLab (Docker) 常用命令及解决方案清单
docker·容器·gitlab
qq_3564086612 天前
GitLab 单机私有化部署文档(基于 Docker 环境)
docker·gitlab
lisanmengmeng14 天前
gitlab 免密配置
linux·服务器·gitlab
求知若渴,虚心若愚。14 天前
Jenkins 自动化流水线(CICD)
运维·自动化·gitlab
mnasd16 天前
Gitlab + Jenkins 实现 CICD
运维·gitlab·jenkins
鹤鸣的日常17 天前
前端运行时动态环境变量方案
前端·react.js·docker·前端框架·vue·gitlab
starvapour17 天前
Ubuntu部署gitlab频繁出现502的问题
linux·ubuntu·gitlab