Fast lookup of authorized SSH keys in the database

原文:https://docs.gitlab.com/ee/administration/operations/fast_ssh_key_lookup.html

Fast lookup of authorized SSH keys in the database

版本历史

注意:本文档介绍了authorized_keys文件的替代品. 对于普通(非部署密钥)用户,请考虑使用SSH 证书 . 它们甚至更快,但不是临时替代品.

随着用户数量的增加,常规的 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 软件包的说明 .

Fast lookup is required for Geo

默认情况下,GitLab 管理一个authorized_keys文件,其中包含允许访问 GitLab 的用户的所有公共 SSH 密钥. 但是,为了维护单个事实来源,需要将Geo配置为通过数据库查找执行 SSH 指纹查找.

作为设置 Geo 的一部分,您将需要对主节点和辅助节点都遵循以下概述的步骤,但是请注意,只需在主节点上取消选中Write to "authorized keys" file复选框,因为它将被选中.如果数据库复制正在工作,则会自动在辅助服务器上反映出来.

Setting up fast lookup via GitLab Shell

GitLab Shell 提供了一种通过对 GitLab 数据库进行快速索引查找来授权 SSH 用户的方法. GitLab Shell 使用 SSH 密钥的指纹来检查用户是否有权访问 GitLab.

将以下内容添加到您的sshd_config文件中. 通常位于/etc/ssh/sshd_config ,但如果使用 Omnibus Docker,它将为/assets/sshd_config

  1. Match User git # Apply the AuthorizedKeysCommands to the git user only
  2. AuthorizedKeysCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-keys-check git %u %k
  3. AuthorizedKeysCommandUser git
  4. Match all # End match, settings apply to all users again

重新加载 OpenSSH:

  1. # Debian or Ubuntu installations
  2. sudo service ssh reload
  3. # CentOS installations
  4. 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是否遵循从源安装的说明. 您可能要考虑在其他地方创建包装脚本,因为此命令需要由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

再次,通过在 UI 中删除用户的 SSH 密钥,添加一个新的 SSH 密钥,然后尝试提取存储库来确认 SSH 是否正常工作.

然后,您可以备份和删除您的authorized_keys文件以获得最佳性能. 当前用户的密钥已经存在于数据库中,因此无需迁移或要求用户重新添加其密钥.

How to go back to using the authorized_keys file

这是一个简短的概述. 请参阅以上说明以获取更多上下文.

  1. Rebuild the 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

对于 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. 首先,下载软件包并安装所需的软件包:

    1. sudo su -
    2. cd /tmp
    3. curl --remote-name https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
    4. tar xzvf openssh-7.5p1.tar.gz
    5. yum install rpm-build gcc make wget openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel
  2. 通过将文件复制到正确的位置来准备构建:

    1. mkdir -p /root/rpmbuild/{SOURCES,SPECS}
    2. cp ./openssh-7.5p1/contrib/redhat/openssh.spec /root/rpmbuild/SPECS/
    3. cp openssh-7.5p1.tar.gz /root/rpmbuild/SOURCES/
    4. cd /root/rpmbuild/SPECS
  3. 接下来,正确设置规格设置:

    1. sed -i -e "s/%define no_gnome_askpass 0/%define no_gnome_askpass 1/g" openssh.spec
    2. sed -i -e "s/%define no_x11_askpass 0/%define no_x11_askpass 1/g" openssh.spec
    3. sed -i -e "s/BuildPreReq/BuildRequires/g" openssh.spec
  4. 建立 RPM:

    1. rpmbuild -bb openssh.spec
  5. 确保已构建 RPM:

    1. ls -al /root/rpmbuild/RPMS/x86_64/

    您应该看到以下内容:

    1. total 1324
    2. drwxr-xr-x. 2 root root 4096 Jun 20 19:37 .
    3. drwxr-xr-x. 3 root root 19 Jun 20 19:37 ..
    4. -rw-r--r--. 1 root root 470828 Jun 20 19:37 openssh-7.5p1-1.x86_64.rpm
    5. -rw-r--r--. 1 root root 490716 Jun 20 19:37 openssh-clients-7.5p1-1.x86_64.rpm
    6. -rw-r--r--. 1 root root 17020 Jun 20 19:37 openssh-debuginfo-7.5p1-1.x86_64.rpm
    7. -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 ,这可能会阻止用户登录,因此请确保在安装后备份并还原了该文件:

    1. timestamp=$(date +%s)
    2. cp /etc/pam.d/sshd pam-ssh-conf-$timestamp
    3. rpm -Uvh /root/rpmbuild/RPMS/x86_64/*.rpm
    4. yes | cp pam-ssh-conf-$timestamp /etc/pam.d/sshd
  7. 验证安装的版本. 在另一个窗口中,尝试登录到服务器:

    1. ssh -v <your-centos-machine>

    您应该看到以下一行:” debug1:远程协议版本 2.0,远程软件版本 OpenSSH_7.5”

    如果没有,则可能需要重新启动sshd (例如systemctl restart sshd.service ).

  8. 重要! 退出之前,请打开与服务器的新 SSH 会话,以确保一切正常! 如果您需要降级,只需安装较旧的软件包即可:

    1. # Only run this if you run into a problem logging in
    2. yum downgrade openssh-server openssh openssh-clients

SELinux support and limitations

在 GitLab 10.5 中引入 .

GitLab 支持SELinux 的 authorized_keys数据库查询.

由于 SELinux 策略是静态的,因此 GitLab 目前不支持更改内部 Unicorn 端口的功能. 管理员必须为环境创建一个特殊的.te文件,因为它不是动态生成的.