SSH 密钥的快速查找
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
当用户数量增长时,SSH 操作会变慢,因为 OpenSSH 会线性搜索 authorized_keys 文件来认证用户。
这个过程需要大量的时间和磁盘 I/O,从而延迟了用户尝试推送或拉取代码仓库的操作。
如果用户频繁添加或删除密钥,操作系统可能不会缓存 authorized_keys 文件,这会导致重复的磁盘读取。
您可以配置 GitLab Shell 来查找 SSH 密钥,而不是使用 authorized_keys 文件。这种方式更快,因为查找操作在 GitLab 数据库中建立了索引。
对于标准(非部署密钥)用户,建议使用 SSH 证书。
它们比数据库查找更快,但并非 authorized_keys 文件的直接替代品。
Geo 需要启用快速查找
- Tier: Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
与 Cloud Native GitLab 不同,Linux 包安装默认会管理一个位于 git 用户主目录下的 authorized_keys 文件。在大多数安装中,该文件位于 /var/opt/gitlab/.ssh/authorized_keys。使用以下命令定位您系统上的 authorized_keys 文件:
getent passwd git | cut -d: -f6 | awk '{print $1"/.ssh/authorized_keys"}'authorized_keys 文件包含所有被授权访问 GitLab 的用户的公钥。然而,为了维护单一可信源,Geo 必须配置为使用数据库查找来执行 SSH 指纹查找。
当您设置 Geo 时,必须为主节点和辅助节点都执行以下步骤。不要在主节点上选择 写入 authorized_keys 文件,因为如果数据库复制正常工作,该操作会自动反映到辅助节点上。
设置快速查找
GitLab Shell 提供了一种通过对 GitLab 数据库进行快速、索引化的查找来授权 SSH 用户的方法。GitLab Shell 使用 SSH 密钥的指纹来检查用户是否有权访问 GitLab。
可以通过以下 SSH 服务器启用快速查找:
gitlab-sshd- OpenSSH
您可以通过为每个服务使用不同的端口来同时运行这两个服务。
使用 gitlab-sshd
要设置 gitlab-sshd,请参阅 gitlab-sshd 文档。
启用 gitlab-sshd 后,GitLab Shell 和 gitlab-sshd 将自动配置为使用快速查找。
使用 OpenSSH
前提条件:
- 需要 OpenSSH 6.9 或更高版本,因为
AuthorizedKeysCommand必须接受指纹。要检查您的版本,请运行sshd -V。
要使用 OpenSSH 设置快速查找:
-
将以下内容添加到您的
sshd_config文件中:Match User git # 仅对 git 用户应用 AuthorizedKeysCommands AuthorizedKeysCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-keys-check git %u %k AuthorizedKeysCommandUser git Match all # 结束匹配,设置再次应用于所有用户该文件通常位于:
- Linux 包安装:
/etc/ssh/sshd_config - Docker 安装:
/assets/sshd_config - 自行编译安装:如果您遵循了从源码安装 GitLab Shell的说明,该命令应位于
/home/git/gitlab-shell/bin/gitlab-shell-authorized-keys-check。建议在其他位置创建一个包装脚本,因为此命令必须由root用户拥有,并且不能被组或其他用户写入。同时,根据需要考虑更改此命令的所有权,但这在gitlab-shell升级期间可能需要临时更改所有权。
- Linux 包安装:
-
重新加载 OpenSSH:
# Debian 或 Ubuntu 安装 sudo service ssh reload # CentOS 安装 sudo service sshd reload -
确认 SSH 是否正常工作:
-
在
authorized_keys文件中注释掉您的用户密钥。为此,请在行首添加#。 -
在您的本地计算机上,尝试拉取一个仓库或运行:
ssh -T git@gitlab.example.com成功的拉取操作或欢迎消息意味着 GitLab 在数据库中找到了密钥,因为该密钥不在文件中。
-
如果查找失败,系统仍会扫描 authorized_keys 文件。
只要这个大文件存在,对于大量用户而言,Git SSH 性能可能仍然很慢。
要解决此问题,您可以禁用对 authorized_keys 文件的写入:
-
确认 SSH 可以正常工作。此步骤很重要,否则文件会很快过时。
-
禁用对
authorized_keys文件的写入:- 在左侧边栏的底部,选择 管理员。
- 选择 设置 > 网络。
- 展开 性能优化。
- 清除 使用
authorized_keys文件认证 SSH 密钥 复选框。 - 选择 保存更改。
-
验证更改:
- 在 UI 中移除您的 SSH 密钥。
- 添加一个新密钥。
- 尝试拉取一个仓库。
-
备份并删除您的
authorized_keys文件。 当前用户的密钥已存在于数据库中,因此无需迁移,也无需用户重新添加他们的密钥。
如何恢复使用 authorized_keys 文件
此概述较为简略。更多上下文信息请参考前面的说明。
- 启用对
authorized_keys文件的写入。- 在左侧边栏的底部,选择 管理员。
- 在左侧边栏,选择 设置 > 网络。
- 展开 性能优化。
- 选中 使用
authorized_keys文件认证 SSH 密钥 复选框。
- 重建
authorized_keys文件。 - 从
/etc/ssh/sshd_config或/assets/sshd_config(如果您使用的是 Linux 包安装的 Docker)中移除AuthorizedKeysCommand行。 - 重新加载
sshd:sudo service sshd reload。
SELinux 支持
GitLab 支持通过 SELinux 进行 authorized_keys 数据库查找。
由于 SELinux 策略是静态的,GitLab 不支持更改内部 Web 服务器端口。管理员必须为环境创建一个特殊的 .te 文件,因为它不是动态生成的。
其他文档
关于 gitlab-sshd 的更多技术文档,请参阅 GitLab Shell 文档。
故障排查
SSH 流量缓慢或 CPU 负载过高
如果您的 SSH 流量缓慢或导致 CPU 负载过高:
- 检查
/var/log/btmp文件的大小。 - 确保它被定期轮转,或在达到一定大小时进行轮转。
如果此文件非常大,GitLab SSH 快速查找可能会导致瓶颈更频繁地出现,从而进一步降低性能。考虑在您的 sshd_config 中禁用 UsePAM,以完全避免读取 /var/log/btmp。
在正在运行的 sshd: git 进程上运行 strace 和 lsof 可以返回调试信息。要获取 IP 为 x.x.x.x 的正在进行中的 Git over SSH 连接的 strace,请运行:
sudo strace -s 10000 -p $(sudo netstat -tp | grep x.x.x.x | egrep 'ssh.*: git' | sed -e 's/.*ESTABLISHED *//' -e 's#/.*##')或者获取正在运行的 Git over SSH 进程的 lsof:
sudo lsof -p $(sudo netstat -tp | egrep 'ssh.*: git' | head -1 | sed -e 's/.*ESTABLISHED *//' -e 's#/.*##')