三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

从CentOS Stream 8的坑说起:一次GitLab SSH密钥认证失败的完整排错实录

从CentOS Stream 8的坑说起:一次GitLab SSH密钥认证失败的完整排错实录

从CentOS Stream 8的坑说起:一次GitLab SSH密钥认证失败的完整排错实录

当你满怀期待地在全新的CentOS Stream 8系统上部署了GitLab,配置好SSH密钥,准备开始高效协作时,却遭遇了一个令人抓狂的问题——每次执行git clone都会提示输入密码,而无论输入什么密码都无济于事。这种看似简单却难以定位的问题,往往最能考验开发者的系统思维和排错能力。本文将带你完整复盘这次排错历程,不仅解决眼前的问题,更重要的是掌握一套通用的故障排查方法论。

1. 问题现象与初步分析

那是一个再普通不过的下午,我在新安装的CentOS Stream 8系统上完成了GitLab EE 14.3.6的部署。按照标准流程创建了管理员账户,配置了SSH密钥对,开放了必要的防火墙端口,并在GitLab上新建了一个测试仓库。一切看起来都很顺利,直到我在Windows 10客户端尝试通过SSH协议克隆仓库:

$ git clone git@server-ip:group/test.git Cloning into 'test'... /c/Users/username/.ssh/config line 2: Unsupported option "rsaauthentication" git@server-ip's password: Permission denied, please try again.

更奇怪的是,使用HTTP协议进行克隆和推送却完全正常。这种"选择性失灵"的现象暗示着问题可能出在SSH协议的特定环节。错误信息中几个关键点值得注意:

  1. Unsupported option "rsaauthentication"提示
  2. 反复要求输入密码但始终认证失败
  3. 最终错误显示Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)

2. 系统性排错:从客户端到服务端

2.1 客户端SSH配置检查

首先从最直接的错误提示入手——.ssh/config文件中不支持的rsaauthentication选项。检查客户端的SSH配置文件:

$ cat ~/.ssh/config Host * RSAAuthentication yes IdentityFile ~/.ssh/id_rsa

原来这是一个过时的SSH配置选项。现代OpenSSH版本中,RSAAuthentication已被PubkeyAuthentication取代。修正后的配置:

Host * PubkeyAuthentication yes IdentityFile ~/.ssh/id_rsa

提示:SSH客户端配置的兼容性问题经常被忽视,特别是当你在多台设备间同步配置文件时,可能包含过时的选项。

2.2 服务端SSH服务验证

修正客户端配置后问题依旧,接下来检查服务端的SSH服务状态:

# 查看SSH服务状态 $ systemctl status sshd # 检查SSH配置文件 $ cat /etc/ssh/sshd_config | grep -v '^#' | grep -v '^$'

重点关注以下几个关键参数:

  • PubkeyAuthentication应为yes
  • PasswordAuthentication通常应为no(强制使用密钥认证)
  • AuthorizedKeysFile应指向正确的位置

确认服务端SSH配置无误后,检查GitLab用户的authorized_keys文件:

$ sudo -u git cat /var/opt/gitlab/.ssh/authorized_keys

2.3 GitLab特定配置排查

当基础SSH环境确认正常后,需要深入GitLab的特定配置。GitLab使用一个名为git的系统用户来处理所有仓库操作,这个用户在安装过程中自动创建:

# 查看git用户信息 $ id git uid=998(git) gid=998(git) groups=998(git) # 检查git用户密码状态 $ sudo passwd -S git git LK 2023-05-01 0 99999 7 -1 (Password locked.)

这里发现一个关键点:GitLab安装时创建的git用户默认密码是被锁定的(LK状态)。这就是为什么系统会不断提示输入密码却始终认证失败——实际上没有一个有效的密码可供验证。

3. 操作系统兼容性:隐藏的罪魁祸首

经过上述排查仍未解决问题,我开始怀疑操作系统兼容性。GitLab官方文档明确列出了支持的操作系统:

操作系统版本官方支持状态备注
CentOS 7完全支持长期支持版本
CentOS 8有限支持已停止维护
CentOS Stream 8不支持滚动更新版本

关键发现:GitLab官方并未提供对CentOS Stream 8的支持!我犯了一个常见错误——使用CentOS 8的安装包在CentOS Stream 8上安装GitLab。

3.1 系统兼容性验证

为验证这一假设,我在另一台CentOS 8服务器上重复安装过程:

# 在CentOS 8上安装GitLab $ curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh | sudo bash $ sudo EXTERNAL_URL="http://gitlab.example.com" yum install -y gitlab-ee

安装完成后,SSH克隆操作立即成功,无需任何密码输入:

$ git clone git@server-ip:group/test.git Cloning into 'test'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done.

3.2 根本原因分析

CentOS Stream 8与CentOS 8虽然版本号相近,但存在本质区别:

  1. 软件包差异:Stream版本包含更多前沿但可能不稳定的更新
  2. SELinux策略:GitLab的SELinux策略模块在Stream上可能不完全兼容
  3. 依赖关系:某些底层库的版本差异可能导致功能异常

特别是SSH相关组件,GitLab依赖特定的PAM和SSH模块配置,这些在非官方支持的系统上可能出现微妙的不兼容问题。

4. 解决方案与最佳实践

基于以上分析,我们有以下几种解决方案:

4.1 推荐方案:使用官方支持的操作系统

最稳妥的方案是迁移到GitLab官方支持的操作系统:

# 备份GitLab数据 $ sudo gitlab-backup create # 在新系统上安装相同版本的GitLab $ curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh | sudo bash $ sudo EXTERNAL_URL="http://gitlab.example.com" yum install -y gitlab-ee=14.3.6-ee.0.el8 # 恢复备份 $ sudo gitlab-ctl stop unicorn $ sudo gitlab-ctl stop sidekiq $ sudo gitlab-backup restore BACKUP=timestamp_of_backup

4.2 临时解决方案:调整SSH认证方式

如果暂时无法更换操作系统,可以尝试以下调整:

  1. 修改GitLab配置,强制使用HTTP协议:
# /etc/gitlab/gitlab.rb gitlab_rails['gitlab_shell_ssh_port'] = 0
  1. 或者为git用户设置有效密码:
$ sudo passwd git
  1. 调整SSH服务配置,启用密码认证:
# /etc/ssh/sshd_config PasswordAuthentication yes

注意:这些临时方案会降低安全性,仅建议在测试环境中使用。

4.3 长期维护建议

为避免类似问题,建议建立以下规范:

  1. 环境标准化

    • 使用Chef/Ansible等工具维护一致的服务器环境
    • 建立基础镜像的版本控制机制
  2. 兼容性检查清单

    • 部署前验证操作系统版本与软件兼容性
    • 关键服务进行端到端测试
  3. 监控与告警

    • 实现GitLab健康状态监控
    • 设置SSH认证失败告警

5. 排错心法与经验总结

这次排错经历让我深刻体会到系统思维的重要性。面对复杂的技术问题,我们需要:

  1. 分层排查:从客户端到服务端,从应用层到底层系统
  2. 对比验证:通过环境对比快速定位差异点
  3. 官方文档:始终作为第一参考来源
  4. 最小化重现:构建最简单的测试场景排除干扰

在GitLab部署场景中,特别需要注意:

  • 操作系统版本与软件包的官方兼容性声明
  • 系统用户的权限和认证配置
  • 网络协议层的细节差异

记得那次凌晨三点的故障排查后,我在笔记本上写下:"在技术领域,最可怕的不是遇到问题,而是遇到问题时没有系统的排错方法。"这次GitLab SSH认证问题的解决,不仅修复了一个具体的故障,更重要的是完善了我的排错工具箱。下次遇到类似问题时,我会先问自己几个关键问题:环境是否符合官方要求?配置是否遵循最佳实践?是否有足够的日志信息?这种结构化思维,往往比记住具体命令更有价值。

← 返回列表