使用已启用 Azure Arc 的服务器对 Azure 资源进行身份验证

直接在已启用 Azure Arc 的服务器上运行的应用程序或进程可以使用托管标识来访问支持基于 Microsoft Entra ID 的身份验证的其他 Azure 资源。 应用程序可以获取代表其标识(由系统分配用于已启用 Azure Arc 的服务器)的访问令牌,并使用该令牌作为“持有者”令牌在其他服务中验证自己的身份。

请参阅托管标识概述文档,获取托管标识的详细说明并了解系统分配的标识和用户分配的标识之间的区别。

本文介绍了服务器如何使用系统分配的托管标识来访问 Azure Key Vault。 Key Vault 使客户端应用程序能够使用机密来访问不受 Microsoft Entra ID 保护的资源。 例如,IIS web 服务器使用的 TLS/SSL 证书可以存储在 Azure Key Vault 中,并安全地将证书部署到 Azure 外部的 Windows 或 Linux 服务器。

安全概述

使用托管标识将服务器加入已启用 Azure Arc 的服务器以进行配置时会发生几个操作(类似于对 Azure VM 执行的操作):

  • Azure 资源管理器收到请求,要求在已启用 Azure Arc 的服务器上启用系统分配的托管标识。

  • Azure 资源管理器在 Microsoft Entra ID 中创建与服务器标识相对应的服务主体。 服务主体在此订阅信任的 Microsoft Entra 租户中创建。

  • Azure 资源管理器通过使用服务主体客户端 ID 和证书更新用于 WindowsLinux 的 Azure 实例元数据服务 (IMDS) 标识终结点来配置服务器上的标识。 终结点是一个 REST 终结点,只能使用众所周知且不可路由的 IP 地址从服务器内部进行访问。 此服务提供一部分有关已启用 Azure Arc 的服务器的元数据信息,以帮助对其进行管理和配置。

在已启用 Azure Arc 的服务器上使用以下变量来配置启用了托管标识的服务器的环境:

  • IMDS_ENDPOINT:已启用 Azure Arc 的服务器的 IMDS 终结点 IP 地址 http://localhost:40342

  • IDENTITY_ENDPOINT:与服务的托管标识 http://localhost:40342/metadata/identity/oauth2/token 对应的 localhost 终结点。

在服务器上运行的代码可以从只能从该服务器中访问的 Azure 实例元数据服务终结点请求令牌。

系统环境变量 IDENTITY_ENDPOINT 用于发现应用程序的标识终结点。 应用程序应尝试检索 IDENTITY_ENDPOINT 和 IMDS_ENDPOINT 值并使用这些值。 允许具有任何访问级别的应用程序向终结点发出请求。 像平常一样对元数据响进行处理,并将其提供给计算机上的任何进程。 但是,当发出的请求会公开令牌时,我们要求客户端提供一个机密来证明他们能够访问仅可供更高特权用户访问的数据。

先决条件

  • 具备托管标识相关知识。

  • 在 Windows 上,你必须是本地管理员组或混合代理扩展应用程序组的成员 。

  • 在 Linux 上,你必须是 himds 组的成员。

  • 使用已启用 Azure Arc 的服务器连接和注册的服务器。

  • 你是订阅或资源组中所有者组的成员(以便执行所需的资源创建和角色管理步骤)。

  • 用于存储和检索凭据的 Azure Key Vault,并将 Azure Arc 标识访问权限分配给 KeyVault。

使用 REST API 获取访问令牌

获取并使用系统分配的托管标识对 Azure 资源进行身份验证的方法与对 Azure VM 进行身份验证的方法类似。

对于已启用 Azure Arc 的 Windows 服务器,使用 PowerShell 时,将调用 Web 请求以从特定端口的本地主机获取令牌。 使用 IP 地址或环境变量 IDENTITY_ENDPOINT 来指定请求。

$apiVersion = "2020-06-01"
$resource = "https://management.chinacloudapi.cn/"
$endpoint = "{0}?resource={1}&api-version={2}" -f $env:IDENTITY_ENDPOINT,$resource,$apiVersion
$secretFile = ""
try
{
    Invoke-WebRequest -Method GET -Uri $endpoint -Headers @{Metadata='True'} -UseBasicParsing
}
catch
{
    $wwwAuthHeader = $_.Exception.Response.Headers["WWW-Authenticate"]
    if ($wwwAuthHeader -match "Basic realm=.+")
    {
        $secretFile = ($wwwAuthHeader -split "Basic realm=")[1]
    }
}
Write-Host "Secret file path: " $secretFile`n
$secret = cat -Raw $secretFile
$response = Invoke-WebRequest -Method GET -Uri $endpoint -Headers @{Metadata='True'; Authorization="Basic $secret"} -UseBasicParsing
if ($response)
{
    $token = (ConvertFrom-Json -InputObject $response.Content).access_token
    Write-Host "Access token: " $token
}

以下响应是返回结果的示例:

使用 PowerShell 成功检索访问令牌。

对于已启用 Azure Arc 的 Linux 服务器,使用 Bash 时,将调用 Web 请求以从特定端口的本地主机获取令牌。 使用 IP 地址或环境变量 IDENTITY_ENDPOINT 来指定以下请求。 若要完成此步骤,需要 SSH 客户端。

CHALLENGE_TOKEN_PATH=$(curl -s -D - -H Metadata:true "http://127.0.0.1:40342/metadata/identity/oauth2/token?api-version=2019-11-01&resource=https%3A%2F%2Fmanagement.chinacloudapi.cn" | grep Www-Authenticate | cut -d "=" -f 2 | tr -d "[:cntrl:]")
CHALLENGE_TOKEN=$(cat $CHALLENGE_TOKEN_PATH)
if [ $? -ne 0 ]; then
    echo "Could not retrieve challenge token, double check that this command is run with root privileges."
else
    curl -s -H Metadata:true -H "Authorization: Basic $CHALLENGE_TOKEN" "http://127.0.0.1:40342/metadata/identity/oauth2/token?api-version=2019-11-01&resource=https%3A%2F%2Fmanagement.chinacloudapi.cn"
fi

以下响应是返回结果的示例:

使用 Bash 成功检索访问令牌。

响应包括访问 Azure 中任意资源所需的访问令牌。 若要完成对 Azure Key Vault 进行身份验证的配置,请参阅访问 Windows 的 Key Vault访问 Linux 的 Key Vault

后续步骤