{{< details >}}

  • Tier: 基础版,专业版,旗舰版
  • Offering: 私有化部署

{{< /details >}}

极狐GitLab 的默认 SSH 认证要求用户在使用 SSH 传输之前上传他们的 SSH 公钥。

在集中式(例如,公司)环境中,这在操作上可能会很麻烦,尤其是当 SSH 密钥是临时密钥时,包括那些在发行后 24 小时后过期的密钥。

在这种设置中,需要一些外部自动化过程来不断将新密钥上传到极狐GitLab。

{{< alert type=”warning” >}}

需要 OpenSSH 版本 6.9+,因为 AuthorizedKeysCommand 必须能够接受指纹。检查您服务器上的 OpenSSH 版本。

{{< /alert >}}

为什么使用 OpenSSH 证书?

当您使用 OpenSSH 证书时,关于哪个极狐GitLab 用户拥有密钥的信息被编码在密钥本身中。OpenSSH 保证用户无法伪造这一点,因为他们需要访问私有 CA 签名密钥。

如果正确设置,这可以完全不再需要将用户 SSH 密钥上传到极狐GitLab。

通过极狐GitLab Shell 设置 SSH 证书查找

我们假设您已经设置了 SSH 证书,并已将您的 CA 的 TrustedUserCAKeys 添加到您的 sshd_config 中,例如:

TrustedUserCAKeys /etc/security/mycompany_user_ca.pub

通常 TrustedUserCAKeys 不会在这种设置中被限制在 Match User git 下,因为它还会用于系统登录到极狐GitLab 服务器本身,但您的设置可能有所不同。如果 CA 仅用于极狐GitLab,请考虑将其放在 Match User git 部分(如下所述)。

该 CA 签发的 SSH 证书 必须 具有与该用户在极狐GitLab 上的用户名相对应的“密钥 ID”,例如(省略了一些输出以简洁起见):

$ ssh-add -L | grep cert | ssh-keygen -L -f -

(stdin):1:
        Type: ssh-rsa-cert-v01@openssh.com user certificate
        Public key: RSA-CERT SHA256:[...]
        Signing CA: RSA SHA256:[...]
        Key ID: "aearnfjord"
        Serial: 8289829611021396489
        Valid: from 2018-07-18T09:49:00 to 2018-07-19T09:50:34
        Principals:
                sshUsers
                [...]
        [...]

从技术上讲,这并不完全正确,例如,如果它是一个 SSH 证书,您通常会以 prod-aearnfjord 用户身份登录服务器,但您必须指定自己的 AuthorizedPrincipalsCommand 来执行该映射,而不是使用我们提供的默认值。

关键部分是 AuthorizedPrincipalsCommand 必须能够从“密钥 ID”映射到极狐GitLab 用户名,因为我们提供的默认命令假设两者之间存在 1=1 的映射。这样做的全部意义在于允许我们从密钥本身提取极狐GitLab 用户名,而不是依赖于类似默认公钥到用户名的映射。

然后,在您的 sshd_config 中为 git 用户设置 AuthorizedPrincipalsCommand。希望您可以使用极狐GitLab 附带的默认命令:

Match User git
    AuthorizedPrincipalsCommandUser root
    AuthorizedPrincipalsCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-principals-check %i sshUsers

该命令发出的输出看起来像:

command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell username-{KEY_ID}",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty {PRINCIPAL}

其中 {KEY_ID} 是传递给脚本的 %i 参数(例如,aeanfjord),{PRINCIPAL} 是传递给它的主体(例如,sshUsers)。

您需要自定义该命令中的 sshUsers 部分。它应该是某个主体,保证是所有能够登录极狐GitLab 的用户密钥的一部分,或者您必须提供一个主体列表,其中一个是用户的,例如:

    [...]
    AuthorizedPrincipalsCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-principals-check %i sshUsers windowsUsers

主体和安全性

您可以提供任意数量的主体,这些主体被转化为 authorized_keys 输出的多行,如 sshd_config(5) 中的 AuthorizedPrincipalsFile 文档所述。

通常在使用 OpenSSH 的 AuthorizedKeysCommand 时,主体是允许登录到该服务器的某个“群组”。然而,在极狐GitLab 中,它仅用于满足 OpenSSH 对它的要求,我们实际上只关心“密钥 ID”是否正确。一旦提取出极狐GitLab 会为该用户执行自己的 ACL(例如,用户可以访问哪些项目)。

因此,在您接受什么时过于慷慨是可以的。例如,如果用户无法访问极狐GitLab,则会产生一条关于无效用户的错误消息。

authorized_keys 文件的交互

如果按上述方式设置 SSH 证书,它们可以与 authorized_keys 文件一起使用,以便 authorized_keys 文件作为回退。

AuthorizedPrincipalsCommand 无法认证用户时,OpenSSH 会恢复检查 ~/.ssh/authorized_keys 文件或使用 AuthorizedKeysCommand。 因此,您可能仍需要在使用 SSH 证书时使用在数据库中快速查找授权的 SSH 密钥

对于大多数用户,SSH 证书通过使用 AuthorizedPrincipalsCommand 处理认证,~/.ssh/authorized_keys 文件主要作为特定情况下的回退,例如部署密钥。然而,根据您的设置,您可能会发现仅为典型用户使用 AuthorizedPrincipalsCommand 是足够的。在这种情况下,authorized_keys 文件仅在自动化部署密钥访问或其他特定场景中是必要的。

考虑典型用户密钥数量(特别是如果它们经常更新)与部署密钥之间的平衡,以帮助您确定在您的环境中是否需要维护 authorized_keys 回退。

其他安全注意事项

用户仍然可以通过手动将 SSH 公钥上传到他们的配置文件来绕过 SSH 证书认证,依赖 ~/.ssh/authorized_keys 回退来认证它。

您可以构建一个检查来强制实施这一限制。例如,提供一个自定义的 AuthorizedKeysCommand,检查从 gitlab-shell-authorized-keys-check 返回的发现的密钥 ID 是否为部署密钥(所有非部署密钥应被拒绝)。

禁用关于用户缺少 SSH 密钥的全局警告

默认情况下,极狐GitLab 会向未上传 SSH 密钥到其配置文件的用户显示“您将无法通过 SSH 拉取或推送项目代码”的警告。

在使用 SSH 证书时,这会适得其反,因为用户不需要上传自己的密钥。

要在全球范围内禁用此警告,请转到“应用程序设置 -> 账户和限制设置”并禁用“显示用户添加 SSH 密钥消息”设置。

此设置专为使用 SSH 证书而添加,但如果您想出于其他原因隐藏警告,也可以在不使用它们的情况下关闭。