如何停止使用虚拟机托管标识扩展并开始使用 Azure 实例元数据服务How to stop using the virtual machine managed identities extension and start using the Azure Instance Metadata Service

托管标识的虚拟机扩展Virtual machine extension for managed identities

托管标识的虚拟机扩展用于请求虚拟机中托管标识的令牌。The virtual machine extension for managed identities is used to request tokens for a managed identity within the virtual machine. 工作流包括以下步骤:The workflow consists of the following steps:

  1. 首先,资源内的工作负荷调用本地终结点 http://localhost/oauth2/token 以请求访问令牌。First, the workload within the resource calls the local endpoint http://localhost/oauth2/token to request an access token.
  2. 然后,虚拟机扩展使用托管标识的凭据从 Azure AD 请求访问令牌。The virtual machine extension then uses the credentials for the managed identity, to request an access token from Azure AD..
  3. 访问令牌将返回到调用方,可用于对支持 Azure AD 身份验证的服务(例如 Azure Key Vault 或 Azure 存储)进行身份验证。The access token is returned to the caller, and can be used to authenticate to services that support Azure AD authentication, like Azure Key Vault or Azure Storage.

由于下一部分所述的多种限制,托管标识 VM 扩展已弃用,用户可以改用 Azure 实例元数据服务 (IMDS) 中的等效终结点Due to several limitations outlined in the next section, the managed identity VM extension has been deprecated in favor of using the equivalent endpoint in the Azure Instance Metadata Service (IMDS)

预配扩展Provision the extension

将虚拟机或虚拟机规模集配置为使用托管标识时,可以选择性地在 Set-AzVMExtension cmdlet 中使用 -Type 参数,来预配 Azure 资源托管标识 VM 扩展。When you configure a virtual machine or virtual machine scale set to have a managed identity, you may optionally choose to provision the managed identities for Azure resources VM extension using the -Type parameter on the Set-AzVMExtension cmdlet. 可以传递 ManagedIdentityExtensionForWindowsManagedIdentityExtensionForLinux(取决于虚拟机的类型),并使用 -Name 参数将其命名。You can pass either ManagedIdentityExtensionForWindows or ManagedIdentityExtensionForLinux, depending on the type of virtual machine, and name it using the -Name parameter. -Settings 参数指定 OAuth 令牌终结点用于令牌获取的端口:The -Settings parameter specifies the port used by the OAuth token endpoint for token acquisition:

   $settings = @{ "port" = 50342 }
   Set-AzVMExtension -ResourceGroupName myResourceGroup -Location ChinaNorth -VMName myVM -Name "ManagedIdentityExtensionForWindows" -Type "ManagedIdentityExtensionForWindows" -Publisher "Microsoft.ManagedIdentity" -TypeHandlerVersion "1.0" -Settings $settings 

还可以使用 Azure 资源管理器部署模板预配 VM 扩展,方法是将以下 JSON 添加到模板中的 resources 节(使用 ManagedIdentityExtensionForLinux 指定名称,使用 type 元素指定 Linux 版本)。You can also use the Azure Resource Manager deployment template to provision the VM extension, by adding the following JSON to the resources section to the template (use ManagedIdentityExtensionForLinux for the name and type elements for the Linux version).

```json
{
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "name": "[concat(variables('vmName'),'/ManagedIdentityExtensionForWindows')]",
    "apiVersion": "2018-06-01",
    "location": "[resourceGroup().location]",
    "dependsOn": [
        "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
    ],
    "properties": {
        "publisher": "Microsoft.ManagedIdentity",
        "type": "ManagedIdentityExtensionForWindows",
        "typeHandlerVersion": "1.0",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "port": 50342
        }
    }
}
```

如果使用虚拟机规模集,则还可以使用 Add-AzVmssExtension cmdlet 来预配 Azure 资源托管标识虚拟机规模集扩展。If you're working with virtual machine scale sets, you can also provision the managed identities for Azure resources virtual machine scale set extension using the Add-AzVmssExtension cmdlet. 可以传递 ManagedIdentityExtensionForWindowsManagedIdentityExtensionForLinux(取决于虚拟机规模集的类型),并使用 -Name 参数将其命名。You can pass either ManagedIdentityExtensionForWindows or ManagedIdentityExtensionForLinux, depending on the type of virtual machine scale set, and name it using the -Name parameter. -Settings 参数指定 OAuth 令牌终结点用于令牌获取的端口:The -Settings parameter specifies the port used by the OAuth token endpoint for token acquisition:

$setting = @{ "port" = 50342 }
$vmss = Get-AzVmss
Add-AzVmssExtension -VirtualMachineScaleSet $vmss -Name "ManagedIdentityExtensionForWindows" -Type "ManagedIdentityExtensionForWindows" -Publisher "Microsoft.ManagedIdentity" -TypeHandlerVersion "1.0" -Setting $settings 

若要使用 Azure 资源管理器部署模板预配虚拟机规模集扩展,请将以下 JSON 添加到模板中的 extensionpProfile 节(使用 ManagedIdentityExtensionForLinux 指定名称,使用 type 元素指定 Linux 版本)。To provision the virtual machine scale set extension with the Azure Resource Manager deployment template, add the following JSON to the extensionpProfile section to the template (use ManagedIdentityExtensionForLinux for the name and type elements for the Linux version).

```json
"extensionProfile": {
    "extensions": [
        {
            "name": "ManagedIdentityWindowsExtension",
            "properties": {
                "publisher": "Microsoft.ManagedIdentity",
                "type": "ManagedIdentityExtensionForWindows",
                "typeHandlerVersion": "1.0",
                "autoUpgradeMinorVersion": true,
                "settings": {
                    "port": 50342
                },
                "protectedSettings": {}
            }
        }
```

由于 DNS 查找失败,虚拟机扩展的预配可能会失败。Provisioning of the virtual machine extension might fail due to DNS lookup failures. 如果发生这种情况,请重启虚拟机,然后重试。If this happens, restart the virtual machine, and try again.

删除扩展Remove the extension

若要删除扩展,请在 Azure CLI 中结合 az vm extension deleteaz vmss extension delete(针对虚拟机规模集)使用 -n ManagedIdentityExtensionForWindows-n ManagedIdentityExtensionForLinux 开关,或者在 Powershell 中使用 Remove-AzVMExtensionTo remove the extension, use -n ManagedIdentityExtensionForWindows or -n ManagedIdentityExtensionForLinux switch (depending on the type of virtual machine) with az vm extension delete, or az vmss extension delete for virtual machine scale sets using Azure CLI, or Remove-AzVMExtension for Powershell:

az vm identity --resource-group myResourceGroup --vm-name myVm -n ManagedIdentityExtensionForWindows
az vmss extension delete -n ManagedIdentityExtensionForWindows -g myResourceGroup -vmss-name myVMSS
Remove-AzVMExtension -ResourceGroupName myResourceGroup -Name "ManagedIdentityExtensionForWindows" -VMName myVM

使用虚拟机扩展获取令牌Acquire a token using the virtual machine extension

下面是使用 Azure 资源托管标识 VM 扩展终结点的示例请求:The following is a sample request using the managed identities for Azure resources VM Extension Endpoint:

GET http://localhost:50342/oauth2/token?resource=https%3A%2F%2Fmanagement.chinacloudapi.cn%2F HTTP/1.1
Metadata: true
元素Element 说明Description
GET HTTP 谓词,指示想要从终结点检索数据。The HTTP verb, indicating you want to retrieve data from the endpoint. 在本例中,该数据为 OAuth 访问令牌。In this case, an OAuth access token.
http://localhost:50342/oauth2/token Azure 资源的托管标识终结点,其中 50342 是可配置的默认端口。The managed identities for Azure resources endpoint, where 50342 is the default port and is configurable.
resource 一个查询字符串参数,表示目标资源的应用 ID URI。A query string parameter, indicating the App ID URI of the target resource. 它也会显示在所颁发令牌的 aud(受众)声明中。It also appears in the aud (audience) claim of the issued token. 本示例请求一个用于访问 Azure 资源管理器的、应用 ID URI 为 https://management.chinacloudapi.cn/ 的令牌。This example requests a token to access Azure Resource Manager, which has an App ID URI of https://management.chinacloudapi.cn/.
Metadata 一个 HTTP 请求标头字段,Azure 资源的托管标识需要使用该元素来缓解服务器端请求伪造 (SSRF) 攻击。An HTTP request header field, required by managed identities for Azure resources as a mitigation against Server Side Request Forgery (SSRF) attack. 必须将此值设置为“true”(全小写)。This value must be set to "true", in all lower case.
object_id (可选)一个查询字符串参数,指示要将此令牌用于的托管标识的 object_id。(Optional) A query string parameter, indicating the object_id of the managed identity you would like the token for. 如果 VM 有用户分配的多个托管标识,则为必需的。Required, if your VM has multiple user-assigned managed identities.
client_id (可选)一个查询字符串参数,指示要将此令牌用于的托管标识的 client_id。(Optional) A query string parameter, indicating the client_id of the managed identity you would like the token for. 如果 VM 有用户分配的多个托管标识,则为必需的。Required, if your VM has multiple user-assigned managed identities.

示例响应:Sample response:

HTTP/1.1 200 OK
Content-Type: application/json
{
  "access_token": "eyJ0eXAi...",
  "refresh_token": "",
  "expires_in": "3599",
  "expires_on": "1506484173",
  "not_before": "1506480273",
  "resource": "https://management.chinacloudapi.cn/",
  "token_type": "Bearer"
}
元素Element 说明Description
access_token 请求的访问令牌。The requested access token. 调用受保护 REST API 时,该令牌将作为“持有者”令牌嵌入在 Authorization 请求标头字段中,使 API 能够对调用方进行身份验证。When calling a secured REST API, the token is embedded in the Authorization request header field as a "bearer" token, allowing the API to authenticate the caller.
refresh_token 未由 Azure 资源的托管标识使用。Not used by managed identities for Azure resources.
expires_in 访问令牌在过期之前保持有效的秒数,从颁发时间开始算起。The number of seconds the access token continues to be valid, before expiring, from time of issuance. 可在令牌的 iat 声明中找到颁发时间。Time of issuance can be found in the token's iat claim.
expires_on 访问令牌过期的时间范围。The timespan when the access token expires. 该日期表示为自“1970-01-01T0:0:0Z UTC”开始的秒数(对应于令牌的 exp 声明)。The date is represented as the number of seconds from "1970-01-01T0:0:0Z UTC" (corresponds to the token's exp claim).
not_before 访问令牌生效且可被接受的时间范围。The timespan when the access token takes effect, and can be accepted. 该日期表示为自“1970-01-01T0:0:0Z UTC”开始的秒数(对应于令牌的 nbf 声明)。The date is represented as the number of seconds from "1970-01-01T0:0:0Z UTC" (corresponds to the token's nbf claim).
resource 请求访问令牌时所针对的资源,与请求的 resource 查询字符串参数匹配。The resource the access token was requested for, which matches the resource query string parameter of the request.
token_type 令牌的类型,这是一个“持有者”访问令牌,意味着资源可向此令牌的持有者授予访问权限。The type of token, which is a "Bearer" access token, which means the resource can give access to the bearer of this token.

排查虚拟机扩展问题Troubleshoot the virtual machine extension

失败后重启虚拟机扩展Restart the virtual machine extension after a failure

在 Windows 和某些 Linux 版本中,如果该扩展停止,可使用以下 cmdlet 手动重启该扩展:On Windows and certain versions of Linux, if the extension stops, the following cmdlet may be used to manually restart it:

Set-AzVMExtension -Name <extension name>  -Type <extension Type>  -Location <location> -Publisher Microsoft.ManagedIdentity -VMName <vm name> -ResourceGroupName <resource group name> -ForceRerun <Any string different from any last value used>

其中:Where:

  • 适用于 Windows 的扩展名称和类型是:ManagedIdentityExtensionForWindowsExtension name and type for Windows is: ManagedIdentityExtensionForWindows
  • 适用于 Linux 的扩展名称和类型是:ManagedIdentityExtensionForLinuxExtension name and type for Linux is: ManagedIdentityExtensionForLinux

尝试 Azure 资源托管标识扩展的架构导出功能时,“自动化脚本”失败"Automation script" fails when attempting schema export for managed identities for Azure resources extension

如果在虚拟机上启用了 Azure 资源托管标识,当尝试将“自动化脚本”功能用于虚拟机或其资源组时,将显示以下错误:When managed identities for Azure resources is enabled on a virtual machine, the following error is shown when attempting to use the "Automation script" feature for the virtual machine, or its resource group:

Azure 资源托管标识自动化脚本导出错误

Azure 资源托管标识虚拟机扩展当前不支持将其架构导出到资源组模板的功能。The managed identities for Azure resources virtual machine extension does not currently support the ability to export its schema to a resource group template. 因此,生成的模板不显示用于在资源上启用 Azure 资源托管标识的配置参数。As a result, the generated template does not show configuration parameters to enable managed identities for Azure resources on the resource. 按照使用模板在 Azure 虚拟机上配置 Azure 资源托管标识中的示例,可以手动添加这些部分。These sections can be added manually by following the examples in Configure managed identities for Azure resources on an Azure virtual machine using a templates.

当架构导出功能可用于 Azure 资源托管标识虚拟机扩展(计划在 2019 年 1 月弃用)时,它将在导出包含 VM 扩展的资源组中列出。When the schema export functionality becomes available for the managed identities for Azure resources virtual machine extension (planned for deprecation in January 2019), it will be listed in Exporting Resource Groups that contain VM extensions.

虚拟机扩展的限制Limitations of the virtual machine extension

使用虚拟机扩展时存在几项主要限制。There are several major limitations to using the virtual machine extension.

  • 最严重的限制是,用于请求令牌的凭据存储在虚拟机上。The most serious limitation is the fact that the credentials used to request tokens are stored on the virtual machine. 成功侵入虚拟机的攻击者可能会盗取凭据。An attacker who successfully breaches the virtual machine can exfiltrate the credentials.
  • 此外,有多个 Linux 分发版仍不支持虚拟机扩展,但这些分发版上修改、生成和测试该扩展需要投入巨大的开发成本。Furthermore, the virtual machine extension is still unsupported by several Linux distributions, with a huge development cost to modify, build and test the extension on each of those distributions. 目前仅支持以下 Linux 分发版:Currently, only the following Linux distributions are supported:
    • CoreOS StableCoreOS Stable
    • CentOS 7.1CentOS 7.1
    • Red Hat 7.2Red Hat 7.2
    • Ubuntu 15.04Ubuntu 15.04
    • Ubuntu 16.04Ubuntu 16.04
  • 使用托管标识部署虚拟机会对性能产生影响,因为还需要预配虚拟机扩展。There is a performance impact to deploying virtual machines with managed identities, as the virtual machine extension also has to be provisioned.
  • 最后,对于每个虚拟机,虚拟机扩展只能支持用户分配的 32 个托管标识。Finally, the virtual machine extension can only support having 32 user-assigned managed identities per virtual machine.

Azure 实例元数据服务Azure Instance Metadata Service

Azure 实例元数据服务 (IMDS) 是一个 REST 终结点,提供有关可用于管理和配置虚拟机的正在运行的虚拟机实例的信息。The Azure Instance Metadata Service (IMDS) is a REST endpoint that provides information about running virtual machine instances that can be used to manage and configure your virtual machines. 该终结点位于已知不可路由的 IP 地址 (169.254.169.254),该地址只能从虚拟机中访问。The endpoint is available at a well-known non-routable IP address (169.254.169.254) that can be accessed only from within the virtual machine.

使用 Azure IMDS 请求令牌可获得多种优势。There are several advantages to using Azure IMDS to request tokens.

  1. 服务位于虚拟机的外部,因此托管标识使用的凭据不再保留在虚拟机上。The service is external to the virtual machine, therefore the credentials used by managed identities are no longer present on the virtual machine. 它们托管在 Azure 虚拟机的主机上并受到保护。Instead, they are hosted and secured on the host machine of the Azure virtual machine.
  2. Azure IaaS 支持的所有 Windows 和 Linux 操作系统都可以使用托管标识。All Windows and Linux operating systems supported on Azure IaaS can use managed identities.
  3. 部署速度更快且更简单,因为不再需要预配 VM 扩展。Deployment is faster and easier, since the VM extension no longer needs to be provisioned.
  4. 使用 IMDS 终结点时,最多可将用户分配的 1000 个托管标识分配到单个虚拟机。With the IMDS endpoint, up to 1000 user-assigned managed identities can be assigned to a single virtual machine.
  5. 与使用虚拟机扩展的请求相比,使用 IMDS 的请求没有明显的变化,因此,可以十分方便地在当前使用虚拟机扩展的现有部署基础上进行移植。There is no significant change to the requests using IMDS as opposed to those using the virtual machine extension, therefore it is fairly simple to port over existing deployments that currently use the virtual machine extension.

由于这些原因,一旦弃用虚拟机扩展,Azure IMDS 服务就会成为请求令牌的不二方法。For these reasons, the Azure IMDS service will be the defacto way to request tokens, once the virtual machine extension is deprecated.

后续步骤Next Steps