# Fast lookup of authorized SSH keys in the database > 原文:[https://docs.gitlab.com/ee/administration/operations/fast_ssh_key_lookup.html](https://docs.gitlab.com/ee/administration/operations/fast_ssh_key_lookup.html) * [Fast lookup is required for Geo](#fast-lookup-is-required-for-geo-premium) * [Setting up fast lookup via GitLab Shell](#setting-up-fast-lookup-via-gitlab-shell) * [How to go back to using the `authorized_keys` file](#how-to-go-back-to-using-the-authorized_keys-file) * [Compiling a custom version of OpenSSH for CentOS 6](#compiling-a-custom-version-of-openssh-for-centos-6) * [SELinux support and limitations](#selinux-support-and-limitations) # Fast lookup of authorized SSH keys in the database[](#fast-lookup-of-authorized-ssh-keys-in-the-database "Permalink") 版本历史 * 在[GitLab Starter](https://about.gitlab.com/pricing/) 9.3 中[引入](https://gitlab.com/gitlab-org/gitlab/-/issues/1631) . * [在](https://gitlab.com/gitlab-org/gitlab/-/issues/3953) GitLab 社区版 10.4 中[可用](https://gitlab.com/gitlab-org/gitlab/-/issues/3953) . **注意:**本文档介绍了`authorized_keys`文件的替代品. 对于普通(非部署密钥)用户,请考虑使用[SSH 证书](ssh_certificates.html) . 它们甚至更快,但不是临时替代品. 随着用户数量的增加,常规的 SSH 操作变得缓慢,这是因为 OpenSSH 通过线性搜索来搜索授权用户的密钥. 在最坏的情况下,例如,当用户无权访问 GitLab 时,OpenSSH 将扫描整个文件以搜索密钥. 这会花费大量时间和磁盘 I / O,这将延迟用户尝试推送或拉到存储库的时间. 更糟糕的是,如果用户频繁添加或删除密钥,则操作系统可能无法缓存`authorized_keys`文件,这将导致磁盘被重复访问. GitLab Shell 通过提供一种通过 GitLab 数据库中的快速索引查找来授权 SSH 用户的方法来解决此问题. 本页介绍如何启用快速查找授权的 SSH 密钥. > **警告:**由于`AuthorizedKeysCommand`必须能够接受指纹,因此需要 OpenSSH 6.9+版本. 这些说明将中断使用较旧版本的 OpenSSH 的安装,例如截至 2017 年 9 月的 CentOS 6 附带的安装.如果要将此功能用于 CentOS 6,请遵循[有关如何构建和安装自定义 OpenSSH 软件包的说明](#compiling-a-custom-version-of-openssh-for-centos-6) . ## Fast lookup is required for Geo[](#fast-lookup-is-required-for-geo-premium "Permalink") 默认情况下,GitLab 管理一个`authorized_keys`文件,其中包含允许访问 GitLab 的用户的所有公共 SSH 密钥. 但是,为了维护单个事实来源,需要将[Geo](../geo/replication/index.html)配置为通过数据库查找执行 SSH 指纹查找. 作为[设置 Geo 的](../geo/replication/index.html#setup-instructions)一部分,您将需要对主节点和辅助节点都遵循以下概述的步骤,但是请注意,只需在主节点上取消选中`Write to "authorized keys" file`复选框,因为它将被选中.如果数据库复制正在工作,则会自动在辅助服务器上反映出来. ## Setting up fast lookup via GitLab Shell[](#setting-up-fast-lookup-via-gitlab-shell "Permalink") GitLab Shell 提供了一种通过对 GitLab 数据库进行快速索引查找来授权 SSH 用户的方法. GitLab Shell 使用 SSH 密钥的指纹来检查用户是否有权访问 GitLab. 将以下内容添加到您的`sshd_config`文件中. 通常位于`/etc/ssh/sshd_config` ,但如果使用 Omnibus Docker,它将为`/assets/sshd_config` : ``` Match User git # Apply the AuthorizedKeysCommands to the git user only AuthorizedKeysCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-keys-check git %u %k AuthorizedKeysCommandUser git Match all # End match, settings apply to all users again ``` 重新加载 OpenSSH: ``` # Debian or Ubuntu installations sudo service ssh reload # CentOS installations sudo service sshd reload ``` 通过注释掉您在`authorized_keys`中的用户密钥(以`#`开头以对其进行注释),并尝试拉出存储库来确认 SSH 是否正常工作. A successful pull would mean that GitLab was able to find the key in the database, since it is not present in the file anymore. **注意:**对于 Omnibus Docker,默认情况下在 GitLab 11.11 及更高版本中设置了`AuthorizedKeysCommand` .**注意:**对于从源安装,该命令位于`/home/git/gitlab-shell/bin/gitlab-shell-authorized-keys-check`是否遵循[从源安装的](../../install/installation.html#install-gitlab-shell)说明. 您可能要考虑在其他地方创建包装脚本,因为此命令需要由`root`拥有,而不能由 group 或其他用户写入. 您也可以考虑根据需要更改此命令的所有权,但这可能需要在`gitlab-shell`升级期间临时更改所有权.**注意:**在确认 SSH 可以正常工作之前,请不要禁用写操作,因为该文件很快就会过时. In the case of lookup failures (which are common), the `authorized_keys` file will still be scanned. So Git SSH performance will still be slow for many users as long as a large file exists. 您可以通过取消选中 GitLab 安装的`Write to "authorized_keys" file` **管理区域">"设置">"网络">"性能优化** `Write to "authorized_keys" file`中的`Write to "authorized_keys" file`来禁用对`authorized_keys`文件的更多写入. [![Write to authorized keys setting](img/f9144e03cf945bcf549c131e2816298f.png)](img/write_to_authorized_keys_setting.png) 再次,通过在 UI 中删除用户的 SSH 密钥,添加一个新的 SSH 密钥,然后尝试提取存储库来确认 SSH 是否正常工作. 然后,您可以备份和删除您的`authorized_keys`文件以获得最佳性能. 当前用户的密钥已经存在于数据库中,因此无需迁移或要求用户重新添加其密钥. ## How to go back to using the `authorized_keys` file[](#how-to-go-back-to-using-the-authorized_keys-file "Permalink") 这是一个简短的概述. 请参阅以上说明以获取更多上下文. 1. [Rebuild the `authorized_keys` file](../raketasks/maintenance.html#rebuild-authorized_keys-file) 2. 启用对"应用程序设置"中的`authorized_keys`文件的写入 3. 如果使用的是 Omnibus Docker,请从`/etc/ssh/sshd_config`或`/assets/sshd_config`删除`AuthorizedKeysCommand`行. 4. Reload `sshd`: `sudo service sshd reload` 5. 删除`/opt/gitlab-shell/authorized_keys`文件 ## Compiling a custom version of OpenSSH for CentOS 6[](#compiling-a-custom-version-of-openssh-for-centos-6 "Permalink") 对于 Ubuntu 16.04 用户而言,无需构建自定义版本的 OpenSSH,因为 Ubuntu 16.04 随 OpenSSH 7.2 一起提供. CentOS 7.4 用户也不需要,因为该版本随 OpenSSH 7.4 一起提供. 如果您使用的是 CentOS 7.0-7.3,我们强烈建议您升级到 CentOS 7.4,而不要遵循此过程. 这应该和运行`yum update`一样简单. CentOS 6 用户必须构建自己的 OpenSSH 软件包才能通过数据库启用 SSH 查找. 以下说明可用于构建 OpenSSH 7.5: 1. 首先,下载软件包并安装所需的软件包: ``` sudo su - cd /tmp curl --remote-name https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz tar xzvf openssh-7.5p1.tar.gz yum install rpm-build gcc make wget openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel ``` 2. 通过将文件复制到正确的位置来准备构建: ``` mkdir -p /root/rpmbuild/{SOURCES,SPECS} cp ./openssh-7.5p1/contrib/redhat/openssh.spec /root/rpmbuild/SPECS/ cp openssh-7.5p1.tar.gz /root/rpmbuild/SOURCES/ cd /root/rpmbuild/SPECS ``` 3. 接下来,正确设置规格设置: ``` sed -i -e "s/%define no_gnome_askpass 0/%define no_gnome_askpass 1/g" openssh.spec sed -i -e "s/%define no_x11_askpass 0/%define no_x11_askpass 1/g" openssh.spec sed -i -e "s/BuildPreReq/BuildRequires/g" openssh.spec ``` 4. 建立 RPM: ``` rpmbuild -bb openssh.spec ``` 5. 确保已构建 RPM: ``` ls -al /root/rpmbuild/RPMS/x86_64/ ``` 您应该看到以下内容: ``` total 1324 drwxr-xr-x. 2 root root 4096 Jun 20 19:37 . drwxr-xr-x. 3 root root 19 Jun 20 19:37 .. -rw-r--r--. 1 root root 470828 Jun 20 19:37 openssh-7.5p1-1.x86_64.rpm -rw-r--r--. 1 root root 490716 Jun 20 19:37 openssh-clients-7.5p1-1.x86_64.rpm -rw-r--r--. 1 root root 17020 Jun 20 19:37 openssh-debuginfo-7.5p1-1.x86_64.rpm -rw-r--r--. 1 root root 367516 Jun 20 19:37 openssh-server-7.5p1-1.x86_64.rpm ``` 6. 安装软件包. OpenSSH 软件包将用其自己的版本替换`/etc/pam.d/sshd` ,这可能会阻止用户登录,因此请确保在安装后备份并还原了该文件: ``` timestamp=$(date +%s) cp /etc/pam.d/sshd pam-ssh-conf-$timestamp rpm -Uvh /root/rpmbuild/RPMS/x86_64/*.rpm yes | cp pam-ssh-conf-$timestamp /etc/pam.d/sshd ``` 7. 验证安装的版本. 在另一个窗口中,尝试登录到服务器: ``` ssh -v ``` 您应该看到以下一行:" debug1:远程协议版本 2.0,远程软件版本 OpenSSH_7.5" 如果没有,则可能需要重新启动`sshd` (例如`systemctl restart sshd.service` ). 8. *重要!* 退出之前,请打开与服务器的新 SSH 会话,以确保一切正常! 如果您需要降级,只需安装较旧的软件包即可: ``` # Only run this if you run into a problem logging in yum downgrade openssh-server openssh openssh-clients ``` ## SELinux support and limitations[](#selinux-support-and-limitations "Permalink") 在 GitLab 10.5 中[引入](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/2855) . GitLab 支持[SELinux 的](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) `authorized_keys`数据库查询. 由于 SELinux 策略是静态的,因此 GitLab 目前不支持更改内部 Unicorn 端口的功能. 管理员必须为环境创建一个特殊的`.te`文件,因为它不是动态生成的.