通过 OpenSSH 的 AuthorizedPrincipalsCommand 查找用户

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

在中心式(例如,公司)环境中,这在操作上可能会很麻烦,特别是如果 SSH 密钥是颁发给用户的临时密钥,包括在颁发后 24 小时过期的密钥。

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

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

为什么使用 OpenSSH 证书?

通过使用 OpenSSH 证书,有关极狐GitLab 上的用户拥有密钥的所有信息都被编码在密钥本身中,OpenSSH 本身保证用户不能伪造,因为他们需要访问私有 CA 签名密钥。

正确设置后,完全消除了将用户 SSH 密钥上传到极狐GitLab 的要求。

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

如何完全设置 SSH 证书超出了本文档的范围。请参阅 OpenSSH 的 PROTOCOL.certkeys。要了解它的工作原理,查看 RedHat 文档

我们假设您已经设置了 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
                [...]
        [...]

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

重要的部分是 AuthorizedPrincipalsCommand 必须能够以某种方式从“密钥 ID” 映射到极狐GitLab 用户名,发布的默认命令假设两者之间存在 1=1 映射,因为重点是允许我们从密钥本身中提取极狐GitLab 用户名,而不是依赖于类似于默认公钥到用户名的映射。

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

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 部分。它应该是某个 Principal,保证是所有可以登录到极狐GitLab 的用户的密钥的一部分,或者您必须提供一个 Principals 列表,其中一个为用户提供,例如:

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

Principals 和安全

您可以根据需要提供任意数量的 Principals,将转换为多行 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/authorized_keys 后备部署密钥(如果您使用这些密钥)。

但是您可能会发现无法这样做,比如当您所有的普通用户都使用快速的 AuthorizedPrincipalsCommand 路径, 并且只有自动部署密钥访问依赖于 ~/.ssh/authorized_keys,或者您拥有的普通用户密钥(特别是如果他们被更新)比部署密钥多得多。

其他安全警告

用户仍然可以通过手动将 SSH 公钥上传到他们的配置文件来绕过 SSH 证书身份验证,依靠 ~/.ssh/authorized_keys 后备来对其进行身份验证。目前没有任何功能可以防止这种情况,但有一个添加它的开放请求。

目前可以通过提供一个自定义的 AuthorizedKeysCommand 来破解这样的限制,该命令检查从 gitlab-shell-authorized-keys-check 返回的发现的密钥 ID 是否是部署密钥(所有非部署密钥应该被拒绝)。

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

默认情况下,系统会向尚未将 SSH 密钥上传到其个人资料的用户显示“您将无法通过 SSH 拉取或推送项目代码”警告。

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

要全局禁用此警告,请转到 应用程序设置 > 账户和限制设置 并禁用 显示用户添加 SSH 密钥消息 设置。

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