使用 SSH 密钥身份验证
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
可以通过 macOS、Linux 或 Windows 上的 SSH 连接到 Git 存储库,以安全地连接到 Azure DevOps。
重要
SSH URL 已更改,但旧的 SSH URL 将继续工作。 如果已设置 SSH,请将远程 URL 更新为新格式:
最新的 SSH URL 以 ssh.dev.azure.com
开头。 先前的 URL 使用 vs-ssh.visualstudio.com
。
- 验证哪些远程库正在使用 SSH。 请改为在 shell 中运行
git remote -v
或使用 GUI 客户端。 - 访问 Web 上的存储库并选择“克隆”。
- 选择 SSH 并复制新的 SSH URL。
- 在 shell 中,针对要更新的每个存储库的远程库运行
git remote set-url <remote name> <new SSH URL>
。 或者,使用 GUI 客户端更新远程 URL。
SSH 密钥身份验证的工作原理
SSH 公钥身份验证使用生成的加密密钥的非对称对。 公钥与 Azure DevOps 共享,用于验证初始 SSH 连接。 私钥在系统上保持安全。
设置 SSH 密钥身份验证
以下步骤介绍了在以下平台上使用命令行(也称为 shell
)配置 SSH 密钥身份验证:
- Linux
- macOS
- 运行 Git for Windows 的 Windows 系统
注意
从 Visual Studio 2017 开始,可以使用 SSH 连接到 Azure DevOps Git 存储库。
步骤 1:创建 SSH 密钥
注意
如果已在系统上创建了 RSA SSH 密钥,请跳过此步骤并配置 SSH 密钥。
若要验证这一点,请转到主目录并查看 .ssh
文件夹(在 Windows 上为 %UserProfile%\.ssh\
,在带有 Git Bash 的 Linux、macOS 和 Windows 上为 ~/.ssh/
)。 如果看到两个分别名为 id_rsa
和 id_rsa.pub
的文件,请继续配置 SSH 密钥。
若要使用基于密钥的身份验证,首先需要为客户端生成公钥/私钥对。 ssh-keygen.exe 用于生成密钥文件,可以指定 DSA、RSA、ECDSA 或 Ed25519 算法。 如果未指定算法,则使用 Ed25519。
注意
Azure DevOps 支持的唯一 SSH 密钥类型是 RSA。
若要使用 Azure DevOps 支持的 RSA 算法(RSA-SHA2-256 或 RSA-SHA2-512)生成密钥文件,请在客户端上从 PowerShell 或其他 shell(如 bash
)运行以下命令之一:
ssh-keygen -t rsa-sha2-256
或
ssh-keygen -t rsa-sha2-512
命令的输出应显示以下输出(用户名在哪里 username
):
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\username/.ssh/id_rsa):
你可以按 Enter 来接受默认值,或指定要在其中生成密钥的路径和/或文件名。 此时,系统会提示你使用密码来加密你的私钥文件。 通行短语可以为空,但不建议这样做。 将密码与密钥文件一起使用来提供双因素身份验证。
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\username/.ssh/id_rsa.
Your public key has been saved in C:\Users\username/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:FHK6WjcUkcfQjdorarzlak1Ob/x7AmqQmmx5ryYYV+8 username@LOCAL-HOSTNAME
The key's randomart image is:
+---[RSA 3072]----+
| . ** o |
| +.o= . |
| . o+ |
| .+. . |
| .ooS . |
| . .oo.=.o |
| =.= O.= . |
| . B BoE + . . |
| . *+*o. .o+ |
+----[SHA256]-----+
现在,在指定的位置中有一个公共/专用 RSA 密钥对。 .pub 文件是公钥,没有扩展名的文件是私钥:
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/11/2022 6:29 PM 2610 id_rsa
-a---- 10/11/2022 6:29 PM 578 id_rsa.pub
重要
切勿共享私钥的内容。 如果私钥已泄露,攻击者可以使用它来欺骗服务器认为连接来自你。 私钥文件等效于密码,应以相同的方式进行保护。
步骤 2:将公钥添加到 Azure DevOps
将上一步中生成的公钥与用户 ID 相关联。
注意
对于你有权访问且想要对其使用 SSH 的每个组织,必须重复此操作。
浏览到 Web 门户,并选择用户界面右上角的头像旁边的图标来打开安全设置。 在显示的菜单中选择 SSH 公钥。
选择 + 新建密钥。
将生成的公钥(例如
id_rsa.pub
)的内容复制到“公钥数据”字段中。重要
不要在“密钥数据”字段中添加空格或换行符,它们可能会导致 Azure DevOps 使用无效的公钥。 粘贴密钥时,通常会在末尾添加换行符。 如果出现此换行符,请务必将其删除。
为密钥提供一个有用的说明(此说明将显示在配置文件的“SSH 公钥”页上),方便在以后记起密码。 选择保存以存储公钥。 密钥一旦保存就无法更改。 可以删除密钥,也可以为另一个密钥创建新条目。 可以添加到用户配置文件的密钥数没有限制。 另请注意,存储在 Azure DevOps 中的 SSH 密钥一年后过期。 如果密钥过期,可以上传新密钥或同一密钥,以继续通过 SSH 访问 Azure DevOps。
在 SSH 公钥概述页上,会显示服务器指纹。 记下首次通过 SSH 连接到 Azure DevOps 时要使用的 SHA256 指纹。
通过运行以下命令来测试连接:
ssh -T git@ssh.dev.azure.com
如果这是第一次连接,应该会收到以下输出:
The authenticity of host 'ssh.dev.azure.com (<IP>)' can't be established. RSA key fingerprint is SHA256:ohD8VZEXGWo6Ez8GSEJQ9WpafgLFsOfLOtGGQCQo6Og. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])?
将指纹与前面提到的 SSH 公钥页上显示的 SHA256 指纹进行比较。 只在两者匹配时才继续!
输入
yes
继续。 如果正确配置了所有内容,输出应如下所示:Warning: Permanently added 'ssh.dev.azure.com' (RSA) to the list of known hosts. remote: Shell access is not supported. shell request failed on channel 0
如果没有,请参阅有关问题和故障排除的部分。
步骤 3:通过 SSH 克隆 Git 存储库
注意
若要将 SSH 与以前通过 HTTPS 克隆的存储库配合使用,请参阅将远程库更新为 SSH。
从 Web 门户复制 SSH 克隆 URL。 在此示例中,SSH 克隆 URL 用于组织中名为 fabrikam-fiber 的存储库,如
dev.azure.com
后面的 URL 第一部分所示。注意
使用 Azure DevOps Services 时,项目 URL 的格式为
dev.azure.com/{your organization}/{your project}
。 但是,仍然支持以前引用visualstudio.com
格式的格式。 有关详细信息,请参阅 Azure DevOps 简介 - 将现有组织切换为使用新的域名 URL。通过命令提示符运行
git clone
。git clone git@ssh.dev.azure.com:v3/fabrikam-fiber/FabrikamFiber/FabrikamFiber
如果未使用 SSH 代理,系统会提示输入通行短语:
Cloning into 'FabrikamFiber'... Enter passphrase for key '/c/Users/username/.ssh/id_rsa': remote: Azure Repos remote: Found 127 objects to send. (50 ms) Receiving objects: 100% (127/127), 56.67 KiB | 2.58 MiB/s, done. Resolving deltas: 100% (15/15), done.
如果系统转而提示你验证指纹,请再次阅读步骤 2:将公钥添加到 Azure DevOps。 有关其他问题,请阅读有关问题和故障排除的部分。
提示
要充分利用 SSH,常见的方法是使用 SSH 代理来管理 SSH 密钥。 不过,设置代理不在本文讲解范围内。
问题和故障排除
问:我看到与 ssh-rsa 相关的警告。 应采取何种操作?
答:你可能会看到两种不同的警告信息:
ssh-rsa is about to be deprecated and your request has been throttled. Please use rsa-sha2-256 or rsa-sha2-512 instead. Your session will continue automatically. For more details see https://devblogs.microsoft.com/devops/ssh-rsa-deprecation.
或
You’re using ssh-rsa that is about to be deprecated and your request has been blocked intentionally. Any SSH session using ssh-rsa is subject to brown out (failure during random time periods). Please use rsa-sha2-256 or rsa-sha2-512 instead. For more details see https://devblogs.microsoft.com/devops/ssh-rsa-deprecation.
如果修改了 SSH 配置,通过将以下内容添加到 ~/.ssh/config
(在 Windows 中为 %UserProfile%\.ssh\config
)文件,以降级 Azure DevOps 的安全设置:
Host ssh.dev.azure.com vs-ssh.visualstudio.com
HostkeyAlgorithms +ssh-rsa
请立即删除这些行,并确保允许 rsa-sha2-256
和/或 rsa-sha2-512
。
有关详细信息,请参阅博客文章。
问:SSH 无法建立连接。 应采取何种操作?
答:你可能会遇到多种不同的问题:
使用不受支持的 ssh-rsa
You’re using ssh-rsa that is unsupported. Please use rsa-sha2-256 or rsa-sha2-512 instead. For more details see https://devblogs.microsoft.com/devops/ssh-rsa-deprecation.
如果修改了 SSH 配置,通过将以下内容添加到
~/.ssh/config
(在 Windows 中为%UserProfile%\.ssh\config
)文件,以降级 Azure DevOps 的安全设置:Host ssh.dev.azure.com vs-ssh.visualstudio.com HostkeyAlgorithms +ssh-rsa
请立即删除这些行,并确保允许
rsa-sha2-256
和/或rsa-sha2-512
。有关详细信息,请参阅博客文章。
没有匹配的主机密钥
如博客文章所述,这种问题既不会发生在 Azure DevOps 服务上,也不会发生在最新的 Azure DevOps Server 版本上。
Unable to negotiate with <IP> port 22: no matching host key type found. Their offer: ssh-rsa
通过将以下内容添加到
~/.ssh/config
文件(在 Windows 中为%UserProfile%\.ssh\config
文件),修改 SSH 配置以降级 Azure DevOps 的安全设置:Host ssh.dev.azure.com vs-ssh.visualstudio.com HostkeyAlgorithms +ssh-rsa
没有匹配的 MAC
Unable to negotiate with <IP> port 22: no matching MAC found. Their offer: hmac-sha2-256,hmac-sha2-512
通过将以下内容添加到
~/.ssh/config
文件(在 Windows 中为%UserProfile%\.ssh\config
文件),修改 SSH 配置以降级 Azure DevOps 的安全设置:Host ssh.dev.azure.com vs-ssh.visualstudio.com MACs +hmac-sha2-512,+hmac-sha2-256
没有匹配的密钥交换方法
Unable to negotiate with <IP> 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256
通过将以下内容添加到
~/.ssh/config
文件(在 Windows 中为%UserProfile%\.ssh\config
文件),修改 SSH 配置以降级 Azure DevOps 的安全设置:Host ssh.dev.azure.com vs-ssh.visualstudio.com KexAlgorithms +diffie-hellman-group-exchange-sha256,+diffie-hellman-group14-sha1,+diffie-hellman-group1-sha1
提示
对于 Azure DevOps Server 和 TFS 的自承载实例,请使用 Host
行中的相应主机名,而不是 ssh.dev.azure.com vs-ssh.visualstudio.com
。
问:如何让 Git 记住我的密钥的密码?
答:可以使用 SSH 代理。 Linux、macOS 和 Windows(从 Windows 10 [内部版本 1809] 开始或通过将 Git for Windows 与 Git Bash 配合使用)均随 SSH 代理一起提供。 SSH 代理可用于缓存 SSH 密钥以供重复使用。 若要详细了解它的使用方式,请参阅 SSH 供应商的手册。
问:我使用 PuTTY 作为 SSH 客户端,并使用 PuTTYgen 生成了密钥。 是否可以将这些密钥用于 Azure DevOps Services?
答: 是的。 使用 PuTTYgen 加载私钥,转到转换菜单,然后选择导出 OpenSSH 密钥。 保存私钥文件,然后按照步骤 设置非默认密钥。 直接从 PuTTYgen 窗口复制公钥,并粘贴到安全设置中的密钥数据字段中。
问:如何验证我上传的公钥是否与我的本地密钥相同?
答:可以使用命令行对公钥运行以下 ssh-keygen
命令来验证上传的公钥的指纹是否与配置文件中显示的指纹匹配。 如果不使用默认值,需要更改路径和公钥文件名。
注意
截至 2024 年 8 月/9 月,我们将从 MD5 迁移到 SHA-256 哈希。 可能需要在转换期间选择正确的函数。
ssh-keygen -l -E md5 -f <path_to_your_public_key> -- use this for MD5 fingerprints
ssh-keygen -l -E sha256 -f <path_to_your_public_key> -- use this for SHA-256 fingerprints
然后,可以将签名与配置文件中的签名进行比较。 此检查非常适合以下情况:将密钥添加到 Azure DevOps 时遇到连接问题或担心将公钥错误地粘贴到“密钥数据”字段中。
问:如何在当前使用 HTTPS 的存储库中开始使用 SSH?
答:需要更新 Git 中的 origin
远程 URL,以便从 HTTPS 切换到 SSH URL。 获得 SSH 克隆 URL 后,运行以下命令:
git remote set-url origin <SSH URL to your repository>
访问名为 origin
的远程库的 Git 命令现在使用 SSH。
问:我在将 Git LFS 与 Azure DevOps Services 配合使用,并拉取 Git LFS 跟踪的文件时收到错误。
答:Azure DevOps Services 目前不支持通过 SSH 使用 LFS。 使用 HTTPS 连接到包含 Git LFS 跟踪文件的存储库。
问:如何使用非默认密钥位置,即 ~/.ssh/id_rsa 和 ~/.ssh/id_rsa.pub?
答:若要使用并非存储在默认位置的密钥,请执行以下两个任务:
密钥必须位于只有你可以读取或编辑的文件夹中。 如果文件夹的权限范围更广,SSH 不会使用这些密钥。
必须让 SSH 知道密钥的位置,例如,在 SSH 配置中将其指定为“标识”:
Host ssh.dev.azure.com IdentityFile ~/.ssh/id_rsa_azure IdentitiesOnly yes
IdentitiesOnly yes
设置可确保 SSH 不会使用任何其他可用标识进行身份验证。 如果有多个标识可用,则此设置尤其重要。
问:我有多个 SSH 密钥。 如何为 Azure DevOps 使用正确的 SSH 密钥?
答:通常,为 SSH 客户端配置多个密钥时,客户端会按顺序尝试对每个密钥进行身份验证,直到 SSH 服务器接受一个密钥。
但是,由于与 SSH 协议和 Git SSH URL 结构相关的技术限制,这种方法不适用于 Azure DevOps。 Azure DevOps 将接受客户端在身份验证期间提供的第一个密钥。 如果该密钥对于请求的存储库来说无效,请求将失败,且由于出现以下错误,不会尝试其他可用密钥:
remote: Public key authentication failed.
fatal: Could not read from remote repository.
对于 Azure DevOps,需要将 SSH 配置为显式使用特定密钥文件。 此过程与使用存储在非默认位置中的密钥时相同。 指示 SSH 为 Azure DevOps 主机使用正确的 SSH 密钥。
问:如何对 Azure DevOps 上的不同组织使用不同的 SSH 密钥?
答:Azure DevOps 将盲目接受客户端在身份验证期间提供的第一个密钥。 如果该密钥对于请求的存储库来说无效,请求将失败并出现以下错误:
remote: Public key authentication failed.
fatal: Could not read from remote repository.
此失败是因为所有 Azure DevOps URL 共享相同的主机名 (ssh.dev.azure.com
),使得 SSH 在默认情况下无法区分它们。 但是,可以通过为每个组织提供不同的密钥来修改 SSH 配置,以区分不同的组织。 使用主机别名在 SSH 配置文件中创建单独的 Host
部分。
# The settings in each Host section are applied to any Git SSH remote URL with a
# matching hostname.
# Generally:
# * SSH uses the first matching line for each parameter name, e.g. if there's
# multiple values for a parameter across multiple matching Host sections
# * "IdentitiesOnly yes" prevents keys cached in ssh-agent from being tried before
# the IdentityFile values we explicitly set.
# * On Windows, ~/.ssh/your_private_key maps to %USERPROFILE%\.ssh\your_private_key,
# e.g. C:\Users\<username>\.ssh\your_private_key.
# Imagine that we have the following two SSH URLs:
# * git@ssh.dev.azure.com:v3/Fabrikam/Project1/fab_repo
# * For this, we want to use `fabrikamkey`, so we'll create `devops_fabrikam` as
# a Host alias and tell SSH to use `fabrikamkey`.
# * git@ssh.dev.azure.com:v3/Contoso/Project2/con_repo
# * For this, we want to use `contosokey`, so we'll create `devops_contoso` as
# a Host alias and tell SSH to use `contosokey`.
#
# To set explicit keys for the two host aliases and to tell SSH to use the correct
# actual hostname, add the next two Host sections:
Host devops_fabrikam
HostName ssh.dev.azure.com
IdentityFile ~/.ssh/private_key_for_fabrikam
IdentitiesOnly yes
Host devops_contoso
HostName ssh.dev.azure.com
IdentityFile ~/.ssh/private_key_for_contoso
IdentitiesOnly yes
之后,不要使用实际 URL,而是通过分别将现有远程库中的主机名替换为 devops_fabrikam
和 devops_contoso
,指示 Git 要将每个存储库的这些 URL 用作远程库。 例如,git@ssh.dev.azure.com:v3/Fabrikam/Project1/fab_repo
将变为 git@devops_fabrikam:v3/Fabrikam/Project1/fab_repo
。
问:我可能会收到哪些有关 SSH 密钥的通知?
答:每当向 Azure DevOps Services 注册新的 SSH 密钥时,你都会收到一封电子邮件通知,提醒你已将新的 SSH 密钥添加到帐户。
问:如果认为其他人正在我的帐户上添加 SSH 密钥,我该怎么办?
答:如果收到未启动的 SSH 密钥注册通知,那么凭据可能会遭到泄露。
下一步是调查密码是否已泄露。 更改密码始终是抵御此攻击途径建议的第一步。 如果你是 Microsoft Entra 用户,请与管理员联系,检查帐户是否从未知源/位置使用。
问:如果系统仍提示输入密码,并且 GIT_SSH_COMMAND="ssh -v" git fetch
显示 no mutual signature algorithm
或 corresponding algo not in PubkeyAcceptedAlgorithms
,我该怎么办?
答:某些 Linux 发行版(例如 Fedora Linux)的加密策略需要比 Azure DevOps 支持的更强大的 SSH 签名算法(截至 2021 年 1 月)。 有一个开放功能请求可用于添加此支持。
可通过将以下代码添加到 SSH 配置 (~/.ssh/config
) 来解决此问题:
Host ssh.dev.azure.com vs-ssh.visualstudio.com
PubkeyAcceptedKeyTypes +ssh-rsa
提示
对于 Azure DevOps Server 和 TFS 的自承载实例,请使用 Host
行中的相应主机名,而不是 ssh.dev.azure.com vs-ssh.visualstudio.com
。