检索实例元数据 - Amazon Elastic Compute Cloud
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

检索实例元数据

由于您的正在运行的实例存在实例元数据,因此您无需使用 Amazon EC2 控制台或 Amazon CLI。这在您编写脚本以实现从实例运行时非常有用。例如,您可从实例元数据访问您的实例的本地 IP 地址来以管理与外部应用程序的连接。

实例元数据可划分成不同类别。有关每个实例元数据类别的描述,请参阅实例元数据类别

要查看正在运行的实例内所有类别的实例元数据,请使用以下 IPv4 或 IPv6 URI。

IPv4

http://169.254.169.254/latest/meta-data/

IPv6

http://[fd00:ec2::254]/latest/meta-data/

IP 地址是链路本地地址,仅从该实例访问时有效。有关更多信息,请参阅本用户指南中的 链路本地地址 和 Wikipedia 上的链路本地地址

注意

本部分中的示例使用 IMDS 的 IPv4 地址:169.254.169.254。如果要通过 IPv6 地址检索 EC2 实例的实例元数据,请确保启用并改用 IPv6 地址:[fd00:ec2::254]。IMDS 的 IPv6 地址与 IMDSv2 命令兼容。IPv6 地址仅可在 基于 Nitro 系统构建的实例 上访问。

根据您使用的是 IMDSv1 还是 IMDSv2,命令格式会有所不同。默认情况下,可以使用 IMDS 的两个版本。要要求使用 IMDSv2,请参阅使用 IMDSv2

您可以使用 PowerShell cmdlet 检索 URI。例如,如果您运行的是 PowerShell 3.0 或更高版本,请使用以下 cmdlet。

IMDSv2
PS C:\> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/

如果您不想使用 PowerShell,则可以安装第三方工具,例如 GNU Wget 或 cURL。

重要

如果您在 Windows 实例上安装第三方工具,请确保您仔细阅读随附的文档,因为调用 HTTP 的方法以及输出格式可能与此处记录的内容不同。

有关从 Linux 实例检索实例元数据的命令,请参阅 Amazon EC2 用户指南(适用于 Windows 实例)中的检索实例元数据

成本

您无需为用于检索实例元数据和用户数据的 HTTP 请求付费。

注意事项

为避免实例元数据检索出现问题,请考虑以下事项:

  • 在容器环境中,我们建议将跃点限制设置为 2。

    默认情况下,Amazon开发工具包使用 IMDSv2 调用。如果 IMDSv2 调用没有收到任何响应,SDK 将重新调用,如果仍然不成功,则使用 IMDSv1。这可能会导致延迟,尤其是在容器环境中。在容器环境中,如果跃点限制为 1,则 IMDSv2 响应不会返回,因为转到容器被视为额外的网络跃点。为避免出现回退到 IMDSv1 的流程以及由此产生的延迟,在容器环境中,我们建议您将跃数限制设置为 2。有关更多信息,请参阅配置实例元数据选项

  • 使用 Sysprep 创建自定义 Windows AMI。

    如果您使用自定义 Windows AMI 启动 Windows 实例,为确保 IMDS 在实例上正常运行,AMI 必须是使用 Sysprep 创建的标准化映像。否则,IMDS 将无法正常运行。

  • 对于 IMDSv2,在检索令牌时必须使用 /latest/api/token

    PUT 请求发放到任何版本特定的路径(例如 /2021-03-23/api/token)将导致元数据服务返回 403 禁止错误。这是预期行为。

  • 如果需要 IMDSv2,则 IMDSv1 不起作用。

    您可以检查某个实例是否需要 IMDSv2,如下所示:选择该实例以查看其详细信息,然后检查 IMDSv2 的值。其值为必需(只能使用 IMDSv2)或可选(可以使用 IMDSv2 和 IMDSv1)。

响应和错误消息

所有实例元数据以文本形式返回(HTTP 内容类型 text/plain)。

特定元数据资源的请求返回相应的值;如果资源不可用,则返回 HTTP 错误代码 404 - Not Found

对通用元数据资源的请求 (以 / 结尾的 URI) 会返回一个可用资源列表,如果此类资源不存在,则会返回 HTTP 错误代码 404 - Not Found。列表中的各个项目位于被换行符 (ASCII 10) 终止的不同的行上。

对于使用 实例元数据服务版本 2 发出的请求,可能会返回以下 HTTP 错误代码:

  • 400 - Missing or Invalid ParametersPUT 请求无效。

  • 401 - UnauthorizedGET 请求使用无效的令牌。建议的措施是生成新的令牌。

  • 403 - Forbidden – 该请求不被允许,或者 IMDS 已关闭。

检索实例元数据的示例

以下示例提供了可以在 Windows 实例上使用的命令。有关从 Linux 实例检索实例元数据的命令,请参阅 Amazon EC2 用户指南(适用于 Windows 实例)中的检索实例元数据

获取实例元数据的可用版本

此示例可以获取实例元数据的可用版本。当有新的实例元数据类别发布时,每个版本都引用一个实例元数据构建。实例元数据构建版本与 Amazon EC2 API 版本不相关。如果您有依赖于以前版本中所存在的结构和信息的脚本,则您可使用早期版本。

注意

为避免每次 Amazon EC2 发布新的实例元数据构建时都必须更新您的代码,我们建议您在路径中使用 latest,而不是版本号。例如,如下所示使用 latest

curl http://169.254.169.254/latest/meta-data/ami-id

IMDSv2
PS C:\> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/ 1.0 2007-01-19 2007-03-01 2007-08-29 2007-10-10 2007-12-15 2008-02-01 2008-09-01 2009-04-04 2011-01-01 2011-05-01 2012-01-12 2014-02-25 2014-11-05 2015-10-20 2016-04-19 ... latest
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/ 1.0 2007-01-19 2007-03-01 2007-08-29 2007-10-10 2007-12-15 2008-02-01 2008-09-01 2009-04-04 2011-01-01 2011-05-01 2012-01-12 2014-02-25 2014-11-05 2015-10-20 2016-04-19 ... latest

获取顶级元数据项

此示例获得顶级元数据项目。有关更多信息,请参阅实例元数据类别

IMDSv2
PS C:\> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ hostname iam/ instance-action instance-id instance-life-cycle instance-type local-hostname local-ipv4 mac metrics/ network/ placement/ profile public-hostname public-ipv4 public-keys/ reservation-id security-groups services/
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ hostname iam/ instance-action instance-id instance-type local-hostname local-ipv4 mac metrics/ network/ placement/ profile public-hostname public-ipv4 public-keys/ reservation-id security-groups services/

以下示例获取在前面的示例中获取的某些顶级元数据项的值。IMDSv2 请求使用在前面的示例命令中创建和存储的令牌,并假设该令牌尚未过期。

IMDSv2
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/ami-id ami-0abcdef1234567890
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/ami-id ami-0abcdef1234567890

 

IMDSv2
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/reservation-id r-0efghijk987654321
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/reservation-id r-0efghijk987654321

 

IMDSv2
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/local-hostname ip-10-251-50-12.ec2.internal
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/local-hostname ip-10-251-50-12.ec2.internal

 

IMDSv2
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/public-hostname ec2-203-0-113-25.compute-1.amazonaws.com
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/public-hostname ec2-203-0-113-25.compute-1.amazonaws.com

获取可用的公有密钥列表

此示例获得可用公有密钥的列表。

IMDSv2
PS C:\> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/public-keys/ 0=my-public-key
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/public-keys/ 0=my-public-key

显示可以使用公有密钥 0 的格式

此示例显示了可以使用公有密钥 0 的格式。

IMDSv2
PS C:\> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key openssh-key
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key openssh-key

获取公有密钥 0(采用 OpenSSH 密钥格式)

此示例获得公有密钥 0 (以 OpenSSH 密钥格式)。

IMDSv2
PS C:\> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key ssh-rsa MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6 b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAd BgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcN MTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYD VQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25z b2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFt YXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ 21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9T rDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpE Ibb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4 nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0Fkb FFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTb NYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE my-public-key
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key ssh-rsa MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6 b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAd BgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wHhcNMTEwNDI1MjA0NTIxWhcN MTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYD VQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25z b2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFt YXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ 21uUSfwfEvySWtC2XADZ4nB+BLYgVIk60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9T rDHudUZg3qX4waLG5M43q7Wgc/MbQITxOUSQv7c7ugFFDzQGBzZswY6786m86gpE Ibb3OhjZnzcvQAaRHhdlQWIMm2nrAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4 nUhVVxYUntneD9+h8Mg9q6q+auNKyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0Fkb FFBjvSfpJIlJ00zbhNYS5f6GuoEDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTb NYiytVbZPQUQ5Yaxu2jXnimvw3rrszlaEXAMPLE my-public-key

获取实例的子网 ID

此示例获取实例的子网 ID。

IMDSv2
PS C:\> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/network/interfaces/macs/02:29:96:8f:6a:2d/subnet-id subnet-be9b61d7
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/network/interfaces/macs/02:29:96:8f:6a:2d/subnet-id subnet-be9b61d7

获取实例的实例标签

在以下示例中,示例实例具有启用实例元数据上的标签和实例标签 Name=MyInstanceEnvironment=Dev

此示例获取实例的所有实例标签键。

IMDSv2
PS C:\> $token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/tags/instance Name Environment
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/tags/instance Name Environment

以下示例获取在上述示例中获取的 Name 密钥的值。IMDSv2 请求使用在前面的示例命令中创建和存储的令牌,并假设该令牌尚未过期。

IMDSv2
PS C:\> Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/tags/instance/Name MyInstance
IMDSv1
PS C:\> Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/tags/instance/Name MyInstance

查询限制

我们基于每个实例来限制对 IMDS 的查询,并且对从实例到 IMDS 的同时连接数进行限制。

如果您使用 IMDS 检索 Amazon 安全凭证,请避免在每个事务期间查询凭证或从大量线程或进程中并发查询凭证,因为这可能会导致节流。相反,我们建议您缓存凭证,直到凭证开始接近其到期时间。有关 IAM 角色以及与其关联的安全凭证的更多信息,请参阅 从实例元数据中检索安全凭证

如果在访问 IMDS 时受到限制,请使用指数回退策略重试查询。

限制 IMDS 访问权限

您可以考虑使用本地防火墙规则,以禁止从某些进程或所有进程中访问 IMDS。

注意

对于 基于 Nitro 系统构建的实例,如果 VPC 内的网络设备(例如虚拟路由器)将数据包转发到 IMDS 地址,且实例的默认源/目标检查被禁用,则可以从您自己的网络访问 IMDS。要防止来自 VPC 外的源访问 IMDS,我们建议您修改网络设备的配置,以丢弃目标 IPv4 地址为 IMDS 169.254.169.254 的数据包,并且如果您启用 IPv6 端点,则丢弃目标 IPv6 地址为 IMDS [fd00:ec2::254] 的数据包。

使用 Windows 防火墙限制访问

以下 PowerShell 示例使用内置的 Windows 防火墙禁止 Internet Information Server Web 服务器(基于其默认安装用户 ID NT AUTHORITY\IUSR)访问 169.254.169.254。它使用拒绝规则 拒绝来自以该用户身份运行的任何进程的所有实例元数据请求(无论是 IMDSv1 还是 IMDSv2)。

PS C:\> $blockPrincipal = New-Object -TypeName System.Security.Principal.NTAccount ("NT AUTHORITY\IUSR") PS C:\> $BlockPrincipalSID = $blockPrincipal.Translate([System.Security.Principal.SecurityIdentifier]).Value PS C:\> $BlockPrincipalSDDL = "D:(A;;CC;;;$BlockPrincipalSID)" PS C:\> New-NetFirewallRule -DisplayName "Block metadata service from IIS" -Action block -Direction out ` -Protocol TCP -RemoteAddress 169.254.169.254 -LocalUser $BlockPrincipalSDDL

或者,您可以考虑使用允许规则 以仅允许特定用户或组进行访问。从安全的角度看,允许规则可能更易于管理,因为它们要求您决定哪种软件需要访问实例元数据。如果使用允许规则,在您以后更改实例上的软件或配置时,不太可能会意外允许软件访问元数据服务(您不打算让该软件进行访问)。您还可以将组与允许规则结合使用,以便您可以在允许的组中添加和删除用户,而无需更改防火墙规则。

以下示例禁止作为 blockPrincipal 变量中指定的操作系统组(在该示例中为 Windows 组 Everyone)运行的所有进程访问实例元数据,但在 exceptionPrincipal 中指定的进程除外(在该示例中为名为 trustworthy-users 的组)。您必须同时指定拒绝委托人和允许委托人,因为与 Linux iptables 中的 ! --uid-owner trustworthy-user 规则不同,Windows 防火墙不提供拒绝所有其他委托人以仅允许特定委托人(用户或组)的快捷方法。

PS C:\> $blockPrincipal = New-Object -TypeName System.Security.Principal.NTAccount ("Everyone") PS C:\> $BlockPrincipalSID = $blockPrincipal.Translate([System.Security.Principal.SecurityIdentifier]).Value PS C:\> $exceptionPrincipal = New-Object -TypeName System.Security.Principal.NTAccount ("trustworthy-users") PS C:\> $ExceptionPrincipalSID = $exceptionPrincipal.Translate([System.Security.Principal.SecurityIdentifier]).Value PS C:\> $PrincipalSDDL = "O:LSD:(D;;CC;;;$ExceptionPrincipalSID)(A;;CC;;;$BlockPrincipalSID)" PS C:\> New-NetFirewallRule -DisplayName "Block metadata service for $($blockPrincipal.Value), exception: $($exceptionPrincipal.Value)" -Action block -Direction out ` -Protocol TCP -RemoteAddress 169.254.169.254 -LocalUser $PrincipalSDDL
注意

要使用本地防火墙规则,您需要修改前面的示例命令以符合您的需求。

使用 netsh 规则限制访问

您可以考虑使用 netsh 规则阻止所有软件,但这些规则不太灵活。

C:\> netsh advfirewall firewall add rule name="Block metadata service altogether" dir=out protocol=TCP remoteip=169.254.169.254 action=block
注意
  • 要使用本地防火墙规则,您需要修改前面的示例命令以符合您的需求。

  • 必须从提升权限的命令提示符中设置 netsh 规则,并且不能将其设置为拒绝或允许特定委托人。