通过 OpenSSH 的 AuthorizedPrincipalsCommand 进行用户查找
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
GitLab 的默认 SSH 身份验证要求用户上传其 SSH 公钥,然后才能使用 SSH 传输。
在集中式(例如企业)环境中,这在操作上可能很麻烦,特别是当 SSH 密钥是颁发给用户的临时密钥时,包括那些在颁发后 24 小时内过期的密钥。
在这样的设置中,需要一些外部自动化流程来不断将新密钥上传到 GitLab。
需要 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。希望您可以使用 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 备用方案来对其进行身份验证。
有一个未解决的问题 要求添加一个设置,以防止用户上传非部署密钥的 SSH 密钥。
您可以构建一个检查来自己强制执行此限制。
例如,提供一个自定义的 AuthorizedKeysCommand,检查从 gitlab-shell-authorized-keys-check 返回的发现密钥 ID 是否是部署密钥(所有非部署密钥都应被拒绝)。
禁用关于用户缺少 SSH 密钥的全局警告
默认情况下,GitLab 向尚未将 SSH 密钥上传到其个人资料的用户显示"您将无法通过 SSH 拉取或推送项目代码"的警告。
使用 SSH 证书时,这会产生反效果,因为用户不需要上传自己的密钥。
要全局禁用此警告,请转到"应用程序设置 -> 账户和限制设置"并禁用"显示用户添加 SSH 密钥消息"设置。
此设置是专门为与 SSH 证书一起使用而添加的,但如果您出于其他原因希望隐藏该警告,也可以在不使用 SSH 证书的情况下将其关闭。