GitLab新用户登录遭遇ERR_TOO_MANY_REDIRECTS:从密码过期到数据库修复的实战排查

发布时间:2026/6/30 1:54:55

GitLab新用户登录遭遇ERR_TOO_MANY_REDIRECTS:从密码过期到数据库修复的实战排查 1. 问题现象诡异的ERR_TOO_MANY_REDIRECTS最近在给团队部署GitLab 16.2.3时遇到个奇怪现象管理员root账号登录一切正常但新建的普通用户首次登录时浏览器疯狂报错ERR_TOO_MANY_REDIRECTS。页面就像个永动机在欢迎页和密码修改页之间来回跳转最终浏览器直接罢工。这个错误表面看是重定向循环但背后其实藏着GitLab的密码过期机制。很多新手遇到这个问题会以为是Nginx配置错误实际上这是GitLab 16.x版本的一个默认安全策略在作祟。我花了三小时排查才发现原来新建用户的密码默认被标记为已过期而系统强制要求修改密码的流程与欢迎页面形成了死循环。2. 根因分析密码过期策略的陷阱2.1 GitLab的默认安全机制GitLab从14.9版本开始引入了密码过期策略默认情况下新建用户密码立即过期password_expires_at当前时间首次登录强制跳转修改密码90天后再次强制修改可通过配置调整这个设计本意是好的但在某些场景下会翻车。当用户访问欢迎页时系统发现密码过期就跳转到修改页修改完成后又跳回欢迎页结果欢迎页再次检测到新密码其实还是首次设置的密码于是又判定需要修改... 完美闭环诞生了。2.2 为什么常规方法失效我试过这些常见解决方案全部扑街重置密码root修改用户密码后登录仍触发循环调整密码有效期参数gitlab.rb里找不到相关配置项提升用户权限即使用户变成管理员照样跳转冻结期限设置修改password_grace_period根本没用关键问题在于这些操作都没真正修改密码的过期状态。通过日志发现系统始终认为用户密码处于待修改状态# 查看GitLab日志 sudo tail -f /var/log/gitlab/gitlab-rails/production.log日志里不断出现Redirected to /users/password/edit Completed 302 Found in 2ms3. 终极解决方案直捣数据库3.1 定位PostgreSQL数据库虽然安装时没特意装PostgreSQL但GitLab其实自带嵌入式PostgreSQL。通过以下命令确认# 查看PostgreSQL数据目录 sudo ls -l /var/opt/gitlab/postgresql/data/ # 检查服务状态 sudo gitlab-ctl status | grep postgres3.2 数据库操作完整流程步骤1进入GitLab的PSQL命令行sudo gitlab-psql -d gitlabhq_production步骤2查询用户信息-- 查看所有用户 SELECT id,username,name,password_expires_at FROM users; -- 示例输出 id | username | name | password_expires_at ------------------------------------------------- 1 | root | Admin | 2 | dev1 | Developer | 2023-12-01 00:00:00步骤3修改过期时间-- 将过期时间设为一个月后 UPDATE users SET password_expires_at (NOW() INTERVAL 30 days) WHERE username dev1; -- 验证修改结果 SELECT username, password_expires_at FROM users WHERE username dev1;关键细节时间格式必须符合PostgreSQL的timestamp标准建议设置未来时间而非NULL避免触发其他异常生产环境建议先备份数据库sudo gitlab-rake gitlab:backup:create3.3 后续操作注意事项清除浏览器缓存重定向状态可能被缓存模拟用户登录测试# 用root模拟用户操作 sudo gitlab-rails console user User.find_by(username: dev1) main_app.user_path(user)可选密码重置# 通过Rails控制台重置密码 sudo gitlab-rails console user User.find_by(username: dev1) user.password 新密码 user.save!4. 预防措施与优化建议4.1 关闭密码过期策略如果不需要该功能可以彻底关闭# 修改/etc/gitlab/gitlab.rb gitlab_rails[password_expiration_enabled] false sudo gitlab-ctl reconfigure4.2 自定义过期时间调整默认90天的策略# 修改/etc/gitlab/gitlab.rb gitlab_rails[password_expiration_days] 365 sudo gitlab-ctl reconfigure4.3 新用户创建最佳实践建议通过API创建用户时直接设置不过期密码curl --request POST \ --header PRIVATE-TOKEN: your_access_token \ --data emailuserexample.compassword初始密码skip_confirmationtruepassword_expires_atnull \ http://gitlab.example.com/api/v4/users5. 深度技术原理5.1 GitLab的认证流程当用户登录时系统会依次检查密码是否正确devise认证密码是否过期PasswordExpiryCheck中间件是否需强制修改RequirePasswordChange模块这个检查链在app/controllers/application_controller.rb中实现before_action :check_password_expiration before_action :required_password_change!5.2 重定向循环的形成问题出在app/helpers/authentication_helper.rbdef store_location_for(resource, location) if resource.require_password_change? super(resource, edit_user_password_path) else super end end一旦require_password_change?返回true所有跳转都会被劫持到密码修改页。6. 替代方案对比方案操作复杂度需要重启风险等级适用场景直接改数据库中否中紧急修复禁用密码过期策略低是低长期解决方案通过API创建用户高否低自动化部署使用Omnibus配置中是中新环境预防7. 常见问题排查Q执行gitlab-psql报错could not change directoryA这是警告不是错误实际已连接成功。可以忽略或先执行cd /QUPDATE语句执行但无效A检查WHERE条件是否准确建议先用SELECT测试Q修改后仍然跳转A可能是浏览器缓存未清理多个用户同名导致更新错记录PostgreSQL事务未提交尝试执行COMMIT;Q找不到gitlab-psql命令A完整路径为/opt/gitlab/embedded/bin/gitlab-psql记得第一次处理这个问题时我差点以为是Nginx配置问题重装了三次才发现是密码策略的坑。现在遇到GitLab登录异常我的排查清单第一位就是检查password_expires_at字段。有些问题看似复杂找准关键点后其实就几行SQL的事。

相关新闻