Amazon Elastic Compute Cloud
用户指南(适用于 Linux 实例)

实例元数据和用户数据

实例元数据 是有关您的实例的数据,可以用来配置或管理正在运行的实例。实例元数据分为几类,例如,主机名、事件和安全组。

您也可以使用实例元数据访问您启动实例时指定的用户数据。例如,您可以指定参数以配置实例,或者包含简单的脚本。您可以构建通用 AMI,并使用用户数据修改启动时提供的配置文件。例如,如果您为各种小型企业运行 Web 服务器,则这些企业可以使用相同的通用 AMI,并在启动时从您在用户数据中指定的 Amazon S3 存储桶中检索其内容。要随时添加新客户,请为客户创建一个存储桶,添加其内容,并使用在用户数据中为您的代码提供的唯一存储桶名称启动 AMI。如果您同时启动多个实例,则用户数据可供该预留中的所有实例使用。属于同一保留的每个实例具有唯一的 ami-launch-index 编号,从而允许您编写代码以控制要执行的操作。例如,第一个主机可能会选择自己作为集群中的初始主节点。有关详细的 AMI 启动示例,请参阅示例:AMI 启动索引值

EC2 实例还可包括动态数据,例如启动实例时生成的实例身份文档。有关更多信息,请参阅动态数据类别

重要

虽然您只能从实例本身中访问实例元数据和用户数据,但并未使用身份验证或加密方法对数据进行保护。任何可以直接访问实例的人以及可能在实例上运行的任何软件都可以查看其元数据。因此,您不应将敏感数据(例如密码或长期保存的加密密钥)存储为用户数据。

配置实例元数据服务

您可以使用以下其中一种方法,从正在运行的实例中访问实例元数据:

  • 实例元数据服务版本 1 (IMDSv1) – 一种请求/响应方法

  • 实例元数据服务版本 2 (IMDSv2) – 一种面向会话的方法

默认情况下,您可以使用 IMDSv1 和/或 IMDSv2。实例元数据服务根据以下条件区分 IMDSv1 和 IMDSv2 请求:对于任何给定请求,PUTGET 标头(对于 IMDSv2 是唯一的)在该请求中是否存在。

您可以在每个实例上配置实例元数据服务,以便本地代码或用户必须使用 IMDSv2。在指定必须使用 IMDSv2 时,IMDSv1 不再起作用。有关更多信息,请参阅配置实例元数据选项

实例元数据服务版本 2 的工作原理

IMDSv2 使用面向会话的请求。对于面向会话的请求,您创建一个会话令牌以定义会话持续时间,该时间最少为 1 秒,最多为 6 小时。在指定的持续时间内,您可以将相同的会话令牌用于后续请求。在指定的持续时间到期后,您必须创建新的会话令牌以用于将来的请求。

以下示例使用 Linux Shell 脚本和 IMDSv2 检索顶级实例元数据项。示例命令:

  • 使用 PUT 请求创建持续 6 小时(21600 秒)的会话令牌

  • 将会话令牌标头存储在名为 TOKEN 的变量中

  • 使用令牌请求顶级元数据项

[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/

在创建令牌后,您可以重复使用令牌,直到令牌过期。在以下示例命令(获取用于启动实例的 AMI 的 ID)中,将重复使用上一示例中的令牌(存储在 $TOKEN 中)。

[ec2-user ~]$ curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/ami-id

在使用 IMDSv2 请求实例元数据时,请求必须包含以下内容:

  1. 使用 PUT 请求启动到实例元数据服务的会话。PUT 请求返回一个令牌,该令牌必须包含在对实例元数据服务的后续 GET 请求中。需要具有该令牌才能使用 IMDSv2 访问元数据。

  2. 将该令牌包含在对实例元数据服务的所有 GET 请求中。如果将令牌使用设置为 required,没有有效令牌或令牌过期的请求将显示 401 - Unauthorized HTTP 错误代码。有关更改令牌使用要求的信息,请参阅 AWS CLI Command Reference 中的 modify-instance-metadata-options

    • 令牌是实例特定的密钥。令牌在其他 EC2 实例上无效,如果尝试在生成令牌的实例外部使用,令牌将会被拒绝。

    • PUT 请求必须包含一个标头,它以秒为单位指定令牌的生存时间 (TTL),最多为 6 小时(21600 秒)。令牌表示一个逻辑会话。TTL 指定令牌的有效时间长度,因而指定会话的持续时间。

    • 在令牌过期后,要继续访问实例元数据,您必须使用另一 PUT 创建新会话。

    • 您可以选择在每个请求中重复使用令牌或创建新的令牌。对于少量请求,在每次需要访问实例元数据服务时生成并立即使用令牌可能更方便。但为了提高效率,您可以为令牌指定更长的持续时间并重复使用令牌,而不必在每次需要请求实例元数据时都编写 PUT 请求。对并发令牌数量没有实际限制,每个令牌表示自己的会话。不过,IMDSv2 仍然受到正常实例元数据服务连接和限制的制约。有关更多信息,请参阅限制

允许在 IMDSv2 实例元数据请求中使用 HTTP GETHEAD 方法。如果 PUT 请求包含 X-Forwarded-For 标头,则会被拒绝。

默认情况下,PUT 请求的响应在 IP 协议级别的响应跃点数限制(生存时间)为 1。如果需要增大跃点数限制,您可以使用 modify-instance-metadata-options 命令进行调整。例如,您可能需要使用更大的跃点数限制,以便与实例上运行的容器服务保持向后兼容。有关更多信息,请参阅 AWS CLI Command Reference 中的 modify-instance-metadata-options

转换为使用 实例元数据服务版本 2

使用 实例元数据服务版本 2 (IMDSv2) 是可选的。将继续无期限支持 实例元数据服务版本 1 (IMDSv1)。如果您选择迁移以使用 IMDSv2,我们建议您使用以下工具和转换途径。

帮助转换为 IMDSv2 的工具

如果您的软件使用 IMDSv1,请使用以下工具帮助重新配置软件,以使用 IMDSv2。

  • AWS 软件:最新版本的 AWS 开发工具包和 CLI 支持 IMDSv2。要使用 IMDSv2,请确保 EC2 实例具有最新版本的 AWS 开发工具包和 CLI。有关更新 CLI 的信息,请参阅 AWS Command Line Interface 用户指南 中的升级到最新版本的 AWS CLI

  • CloudWatch:IMDSv1 不使用支持令牌的会话。您可以通过 CloudWatch 指标 MetadataNoToken 跟踪未使用支持令牌的会话的实例元数据服务调用数。该指标跟踪使用 IMDSv1 的调用数。通过查看该指标是否为零,您可以确定是否以及何时将所有软件升级为使用 IMDSv2。有关更多信息,请参阅实例指标

  • EC2 API 和 CLI 更新:对于现有实例,您可以使用 modify-instance-metadata-options CLI 命令(或 ModifyInstanceMetadataOptions API)以要求使用 IMDSv2。对于新实例,您可以使用 run-instances CLI 命令(或 RunInstances API)和 metadata-options 参数以启动要求使用 IMDSv2 的新实例。

  • IAM 策略和 SCP:您可以使用条件键阻止用户启动新实例或修改正在运行的实例,除非他们指定仅使用 IMDSv2。您还可以使用另一个条件键,阻止使用通过 IMDSv1 获取的 EC2 角色凭证进行的后续 API 调用。可以在 IAM 策略或 AWS Organizations 服务控制策略 (SCP) 中使用这些条件键,如下一节中所述。有关更多信息,请参阅下一节中的将所有实例转换为 IMDSv2 时

要求 IMDSv2 访问的建议途径

在使用上述工具时,我们建议您按照以下途径转换为 IMDSv2:

  1. 在开始时

    将在 EC2 实例上使用角色凭证的开发工具包、CLI 和软件更新为与 IMDSv2 兼容的版本。然后,使用 IMDSv2 请求更改直接访问实例元数据的软件(换句话说,不使用开发工具包)。有关更新 CLI 的信息,请参阅 AWS Command Line Interface 用户指南 中的升级到最新版本的 AWS CLI

  2. 在转换期间

    查看 CloudWatch 指标 MetadataNoToken 以跟踪转换进度,该指标显示对实例上的 IMDSv1 的调用次数。有关更多信息,请参阅实例指标

  3. 在所有实例上一切准备就绪时

    在 CloudWatch 指标 MetadataNoToken 记录使用次数为零时,说明在所有实例上一切准备就绪。在该阶段,您可以通过 modify-instance-metadata-options 命令要求使用 IMDSv2。您可以在正在运行的实例上进行这些更改,而无需重新启动实例。对于新启动的实例,您可以使用 run-instances 命令指定将仅使用 IMDSv2。只能通过 API 或 AWS CLI 指定实例元数据选项;目前,无法通过 AWS 管理控制台 指定这些选项。有关更多信息,请参阅 AWS CLI Command Reference 中的 run-instancesmodify-instance-metadata-options

  4. 将所有实例转换为 IMDSv2 时

    您可以使用 IAM 条件强制要求,除非实例使用 IMDSv2,否则,IAM 用户不能启动实例。有关更多信息,请参阅下一节中的在所有新实例上强制使用 IMDSv2。您也可以使用 IAM 条件强制要求 IAM 用户不能修改正在运行的实例以重新启用 IMDSv1,以及强制要求在实例上提供实例元数据服务。

    此外,您还可以选择额外的保护层以强制从 IMDSv1 更改为 IMDSv2。在与通过 EC2 角色凭证调用的 API 相关的访问管理层上,您可以在 IAM 策略或 AWS Organizations 服务控制策略 (SCP) 中使用新的条件键。具体来说,通过在 IAM 策略中使用值为 2.0 的策略条件键 ec2:RoleDelivery,使用从 IMDSv1 获取的 EC2 角色凭证进行的 API 调用将显示 Access Denied 响应。通过使用 SCP 所需的该条件,可以更广泛地实现相同的效果。这会确保通过 IMDSv1 提供的凭证不能实际用于调用 API,因为任何不符合指定条件的 API 调用将会出现 Access Denied 错误。有关更多信息,请参阅 AWS Organizations 用户指南 中的服务控制策略

配置实例元数据选项

通过使用实例元数据选项,您可以配置新实例或现有实例以要求在请求实例元数据时使用 IMDSv2,指定 PUT 响应跃点数限制以及禁止访问实例元数据。您还可以在 IAM 策略或 SCP 中使用条件键以仅在实例配置为要求使用 IMDSv2 时启动实例,限制允许的跃点数或强制要求完全禁用 IMDS。要在新实例或现有实例上配置实例元数据选项,您可以使用 AWS 开发工具包或 CLI。有关更多信息,请参阅 AWS CLI Command Reference 中的 run-instancesmodify-instance-metadata-options

注意

在进行任何更改之前,您应谨慎执行操作并进行仔细的测试。记录以下内容:

  • 如果您强制使用 IMDSv2,则使用 IMDSv1 访问实例元数据的应用程序或代理将会中断。

  • 如果禁用对实例元数据的所有访问,则依赖于实例元数据访问才能正常工作的应用程序或代理将会中断。

在所有新实例上强制使用 IMDSv2

要确保 IAM 用户只能启动要求在请求实例元数据时使用 IMDSv2 的实例,您可以指定在启动实例之前要求 IMDSv2 必须满足的条件。

以下说明介绍如何使用 AWS CLI 创建并附加策略。有关如何使用 AWS 管理控制台的说明,请参阅 IAM 用户指南 中的创建 IAM 策略(控制台)将策略直接附加到用户以添加权限

  1. 创建一个 JSON 策略文档,其中包含以下内容:

    • ec2:RunInstances 操作。这会为 IAM 用户授予权限以启动新的实例。

    • 设置为 requiredec2:MetadataHttpTokens 条件。这指定了以下条件:要启动实例,必须将其配置为要求使用 IMDSv2,这会在实例元数据检索请求中使用安全令牌标头。

    下面是示例策略文档。

    { "Version": "2012-10-17", "Statement": [{ "Sid": "RunInstanceWithImdsV2Only", "Effect": "Allow", "Action": "ec2:RunInstances", "Resource": "*", "Condition": { "StringEquals": { "ec2:MetadataHttpTokens": "required" } } }] }
  2. 使用 create-policy 命令创建新的托管策略,并指定您创建的 JSON 文档以作为新策略的内容。

    $ aws iam create-policy --policy-name my-policy --policy-document file://JSON-file-name
  3. 使用 attach-user-policy 命令将托管策略附加到指定的 IAM 用户。对于 --user-name 参数,请指定 IAM 用户的友好名称(而不是 ARN)。

    $ aws iam attach-user-policy --policy-arn arn:aws:iam::account-id:policy/my-policy --user-name IAM-friendly-name

也可以使用 ec2:MetadataHttpTokensec2:MetadataHttpPutResponseHopLimitec2:MetadataHttpEndpoint IAM 条件键,以控制使用 RunInstancesModifyInstanceMetadataOptions API 以及相应的 CLI。有关这些键的有效条件,请参阅 AWS CLI Command Reference 中的 run-instancesmodify-instance-metadata-options。如果创建了策略,并且 API 调用中的参数与使用条件键的策略中指定的状态不匹配,API 或 CLI 调用将失败并显示 Access Denied 响应。您可以将前面的示例策略作为一个示例,以了解如何使用这些条件键创建策略。

要求在现有实例上使用 IMDSv2

对于现有的实例,您可以选择要求在请求实例元数据时使用 IMDSv2。请使用 modify-instance-metadata-options CLI 命令,并将 http-tokens 参数设置为 required

aws ec2 modify-instance-metadata-options --instance-id i-1234567898abcdef0 --http-tokens required

虽然我们未提供示例策略,但也可以使用 ec2:MetadataHttpTokens 条件键控制使用 ModifyInstanceMetadataOptions API 以及 RunInstances API。

更改现有实例上的 PUT 响应跃点数限制

对于现有的实例,您可以更改 PUT 响应跃点数限制设置。请使用 modify-instance-metadata-options CLI 命令,并将 http-put-response-hop-limit 参数设置为所需的跃点数。在以下示例中,跃点数限制设置为 3

aws ec2 modify-instance-metadata-options --instance-id i-1234567898abcdef0 --http-put-response-hop-limit 3

在现有实例上禁用实例元数据访问

对于现有的实例,您可以禁用实例元数据服务的 HTTP 终端节点以禁用实例元数据访问,而无论使用的是哪种实例元数据服务版本。您可以随时启用 HTTP 终端节点以撤消该更改。请使用 modify-instance-metadata-options CLI 命令,并将 http-endpoint 参数设置为 disabled

aws ec2 modify-instance-metadata-options --instance-id i-1234567898abcdef0 --http-endpoint disabled

检索实例元数据

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

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

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

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

IP 地址 169.254.169.254 是链路本地地址,仅从该实例有效。有关更多信息,请参阅 Wikipedia 上的链路本地地址

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

根据您使用的是 IMDSv1 还是 IMDSv2,命令格式会有所不同。默认情况下,您可以使用两种实例元数据服务。要要求使用 IMDSv2,请参阅配置实例元数据服务

您可以使用 cURL 等工具,如以下示例中所示。

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/

您也可以下载实例元数据查询工具,以通过实例元数据服务 1.0 版查询实例元数据,而不必输入完整 URI 或类别名称。

响应和错误消息

所有实例元数据以文本形式返回(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 – 不允许该请求,或禁用了实例元数据服务。

检索实例元数据的示例

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

此示例可以获取实例元数据的可用版本。这些版本不一定与 Amazon EC2 API 版本相关联。如果您有依赖于以前版本中所存在的结构和信息的脚本,则您可使用早期版本。

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v 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 2016-06-30 2016-09-02 latest
IMDSv1
[ec2-user ~]$ curl 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 2016-06-30 2016-09-02 latest

获取顶级元数据项

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

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/latest/meta-data/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ events/ 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/
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ events/ 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 请求使用在前面的示例命令中创建和存储的令牌,并假设该令牌尚未过期。

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/ami-id ami-0abcdef1234567890
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/ami-id ami-0abcdef1234567890

 

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/reservation-id r-0efghijk987654321
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/reservation-id r-0efghijk987654321

 

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/local-hostname ip-10-251-50-12.ec2.internal
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/local-hostname ip-10-251-50-12.ec2.internal

 

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/public-hostname ec2-203-0-113-25.compute-1.amazonaws.com
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/public-hostname ec2-203-0-113-25.compute-1.amazonaws.com

获取可用的公有密钥列表

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

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ `curl -X PUT "http://169.254.169.254/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/public-keys/ 0=my-public-key
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/public-keys/ 0=my-public-key

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

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

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/public-keys/0/ openssh-key
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/public-keys/0/ openssh-key

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

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

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v 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
[ec2-user ~]$ curl 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。

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/network/interfaces/macs/02:29:96:8f:6a:2d/subnet-id subnet-be9b61d7
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/02:29:96:8f:6a:2d/subnet-id subnet-be9b61d7

限制

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

如果您使用实例元数据服务检索 AWS 安全凭证,请避免在每个事务期间查询凭证或从大量线程或进程中并发查询凭证,因为这可能会导致受到限制。相反,我们建议您缓存凭证,直到凭证开始接近其到期时间。

如果在访问实例元数据服务时受到限制,请使用指数回退策略重试查询。

限制实例元数据服务访问

您可以考虑使用本地防火墙规则,以禁止从某些或所有进程中访问实例元数据服务。

使用 iptables 限制访问

以下示例使用 Linux iptables 及其 owner 模块禁止 Apache Web 服务器(基于其默认安装用户 ID apache)访问 169.254.169.254。它使用拒绝规则 拒绝来自以该用户身份运行的任何进程的所有实例元数据请求(无论是 IMDSv1 还是 IMDSv2)。

$ sudo iptables --append OUTPUT --proto tcp --destination 169.254.169.254 --match owner --uid-owner apache --jump REJECT

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

以下示例禁止所有进程访问实例元数据服务,但在用户账户 trustworthy-user 中运行的进程除外。

$ sudo iptables --append OUTPUT --proto tcp --destination 169.254.169.254 --match owner ! --uid-owner trustworthy-user --jump REJECT

注意

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

  • 默认情况下,不会在系统重新引导之间持久保留 iptables 规则。可以使用此处未介绍的操作系统功能持久保留这些规则。

  • 只有在组是给定本地用户的主要组时,iptables owner 模块才会匹配组成员资格。不会匹配其他组。

使用 PF 或 IPFW 限制访问

如果使用 FreeBSD 或 OpenBSD,您也可以考虑使用 PF 或 IPFW。以下示例将实例元数据服务访问限制为仅根用户。

PF

$ block out inet proto tcp from any to 169.254.169.254
$ pass out inet proto tcp from any to 169.254.169.254 user root

IPFW

$ allow tcp from any to 169.254.169.254 uid root
$ deny tcp from any to 169.254.169.254

注意

PF 和 IPFW 命令的顺序至关重要。PF 默认为最后一个匹配规则,而 IPFW 默认为第一个匹配规则。

与实例用户数据配合使用

与实例用户数据配合使用时,请注意以下内容:

  • 用户数据必须采用 base64 编码。Amazon EC2 控制台可以为您执行 base64 编码或接受 base64 编码的输入。

  • 用户数据在进行 base64 编码之前的原始格式的大小限制为 16 KB。长度为 n 的字符串在进行 base64 编码之后的大小为 ceil(n/3)*4。

  • 在检索用户数据时,必须对其进行 base64 解码。如果您使用实例元数据或控制台检索数据,则会自动对数据进行解码。

  • 用户数据会被视为非透明数据;您提供什么数据您就会得到什么数据。由实例对其进行解释。

  • 如果您停止实例,修改用户数据,然后启动实例,则在启动实例时,不会执行更新后的用户数据。

启动时指定实例用户数据

您可在启动实例时指定用户数据。有关更多信息,请参阅 使用启动实例向导启动实例启动时在 Linux 实例上运行命令

修改实例用户数据

如果根卷是 EBS 卷,则可以修改处于停止状态的实例的用户数据。有关更多信息,请参阅 查看和更新实例用户数据

检索实例用户数据

要从正在运行的实例中检索用户数据,请使用以下 URI。

http://169.254.169.254/latest/user-data

请求用户数据时,按原样返回数据 (内容类型 application/octet-stream)。

该示例返回以逗号分隔文本形式提供的用户数据。

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/user-data 1234,john,reboot,true | 4512,richard, | 173,,,
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/user-data 1234,john,reboot,true | 4512,richard, | 173,,,

该示例返回以脚本形式提供的用户数据。

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/user-data #!/bin/bash yum update -y service httpd start chkconfig httpd on
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/user-data #!/bin/bash yum update -y service httpd start chkconfig httpd on

要从您自己的计算机检索实例的用户数据,请参阅用户数据和 AWS CLI

检索动态数据

要从正在运行的实例中检索动态数据,请使用以下 URI。

http://169.254.169.254/latest/dynamic/

该示例说明了如何检索简要的实例身份类别。

IMDSv2IMDSv1
IMDSv2
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/dynamic/instance-identity/ rsa2048 pkcs7 document signature dsa2048
IMDSv1
[ec2-user ~]$ curl http://169.254.169.254/latest/dynamic/instance-identity/ rsa2048 pkcs7 document signature dsa2048

有关动态数据的详细信息和如何对其进行检索的示例,请参阅 实例身份文档

示例:AMI 启动索引值

本示例演示如何使用用户数据和实例元数据来配置实例。

Alice 想要启动她最喜欢的 数据库 AMI 的四个实例,第一个实例用作主实例,其余三个用作副本。当她启动它们时,她想为每个副本添加有关复制策略的用户数据。她知道这些数据将对所有四个实例都可用,因此她所采用的用户数据构建方式必须能够让每个实例识别出哪些部分适用于自己。她可通过 ami-launch-index 实例元数据值来实现这一点,该值对每个实例都是唯一的。

以下是 Alice 构建的用户数据。

replicate-every=1min | replicate-every=5min | replicate-every=10min

replicate-every=1min 数据定义第一个副本的配置,replicate-every=5min 定义第二个副本的配置,以此类推。Alice 决定以 ASCII 字符串形式提供这些数据,用竖线符号 (|) 来分隔每个实例的数据。

Alice 使用 run-instances 命令启动 4 个实例,并指定用户数据。

aws ec2 run-instances --image-id ami-0abcdef1234567890 --count 4 --instance-type t2.micro --user-data "replicate-every=1min | replicate-every=5min | replicate-every=10min"

实例启动之后,所有实例都有以下用户数据和常用元数据的副本:

  • AMI id: ami-0abcdef1234567890

  • 预留 ID:r-1234567890abcabc0

  • 公有密钥:无

  • 安全组名称:默认值

  • 实例类型:t2.micro

然而,每个实例都包含某些特定的元数据。

实例 1

元数据
instance-id i-1234567890abcdef0
ami-launch-index 0
public-hostname ec2-203-0-113-25.compute-1.amazonaws.com
public-ipv4 67.202.51.223
local-hostname ip-10-251-50-12.ec2.internal
local-ipv4 10.251.50.35

实例 2

元数据
instance-id i-0598c7d356eba48d7
ami-launch-index 1
public-hostname ec2-67-202-51-224.compute-1.amazonaws.com
public-ipv4 67.202.51.224
local-hostname ip-10-251-50-36.ec2.internal
local-ipv4 10.251.50.36

实例 3

元数据
instance-id i-0ee992212549ce0e7
ami-launch-index 2
public-hostname ec2-67-202-51-225.compute-1.amazonaws.com
public-ipv4 67.202.51.225
local-hostname ip-10-251-50-37.ec2.internal
local-ipv4 10.251.50.37

实例 4

元数据
instance-id i-1234567890abcdef0
ami-launch-index 3
public-hostname ec2-67-202-51-226.compute-1.amazonaws.com
public-ipv4 67.202.51.226
local-hostname ip-10-251-50-38.ec2.internal
local-ipv4 10.251.50.38

Alice 可以使用 ami-launch-index 值确定用户数据的哪个部分适用于特定实例。

  1. 她连接到其中一个实例并检索该实例的 ami-launch-index,以确保该实例是副本之一:

    IMDSv2IMDSv1
    IMDSv2
    [ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/meta-data/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/ami-launch-index 2

    对于以下步骤,IMDSv2 请求使用前面的 IMDSv2 命令中存储的令牌,并假设令牌尚未过期。

    IMDSv1
    [ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/ami-launch-index 2
  2. 她将 ami-launch-index 保存为一个变量。

    IMDSv2IMDSv1
    IMDSv2
    [ec2-user ~]$ ami_launch_index=`curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/ami-launch-index`
    IMDSv1
    [ec2-user ~]$ ami_launch_index=`curl http://169.254.169.254/latest/meta-data/ami-launch-index`
  3. 她将用户数据保存为一个变量。

    IMDSv2IMDSv1
    IMDSv2
    [ec2-user ~]$ user_data=`curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/user-data`
    IMDSv1
    [ec2-user ~]$ user_data=`curl http://169.254.169.254/latest/user-data`
  4. 最后,Alice 使用 cut 命令提取适用于该实例的用户数据部分。

    IMDSv2IMDSv1
    IMDSv2
    [ec2-user ~]$ echo $user_data | cut -d"|" -f"$ami_launch_index"replicate-every=5min
    IMDSv1
    [ec2-user ~]$ echo $user_data | cut -d"|" -f"$ami_launch_index" replicate-every=5min

实例元数据类别

下表列举了实例元数据的类别。

重要

使用红色文本格式的类别名称是您的实例中唯一的数据的占位符;例如 mac 表示网络接口的 MAC 地址。您必须使用实际值替换占位符。

数据 描述 引入的版本
ami-id 用于启动实例的 AMI ID。 1.0
ami-launch-index 如果您同时启动了多个实例,此值表示实例启动的顺序。第一个启动的实例的值是 0。 1.0
ami-manifest-path 指向 Amazon S3 中的 AMI 清单文件的路径。如果您使用 Amazon EBS 支持的 AMI 来启动实例,则返回的结果为 unknown 1.0
ancestor-ami-ids 为创建此 AMI 而重新绑定的任何实例的 AMI ID。仅当 AMI 清单文件包含一个 ancestor-amis 密钥时,此值才存在。 2007-10-10
block-device-mapping/ami 包含根/启动文件系统的虚拟设备。 2007-12-15
block-device-mapping/ebs 与任何 Amazon EBS 卷关联的虚拟设备。仅当 Amazon EBS 卷在启动时存在或者在上一次启动该实例时存在时,这些卷才在元数据中可用。N 表示 Amazon EBS 卷的索引(例如 ebs1ebs2)。 2007-12-15
block-device-mapping/ephemeral 任何非 NVMe 实例存储卷的虚拟设备。N 表示每个卷的索引。块储存设备映射中的实例存储卷数可能与实例的实际实例存储卷数不匹配。实例类型将决定对实例可用的实例存储卷的数量。如果块储存设备映射中的实例存储卷数超过了对实例可用的实例存储卷数,则其他实例存储卷将被忽略。 2007-12-15
block-device-mapping/root 与根设备关联的虚拟设备或分区或虚拟设备上的分区,其中根(/ 或 C:)文件系统与给定实例相关联。 2007-12-15
block-device-mapping/swap swap 关联的虚拟设备。并不总是存在。 2007-12-15
elastic-gpus/associations/elastic-gpu-id 如果有 Elastic GPU 附加到实例,在有关 Elastic GPU 的信息中包含 JSON 字符串,包括其 ID 和连接信息。 2016-11-30
elastic-inference/associations/eia-id 如果有 Elastic Inference 加速器附加到实例,则在有关Elastic Inference 加速器的信息中包含一个 JSON 字符串,包括其 ID 和类型。 2018-11-29
events/maintenance/history 如果实例存在已完成或已取消的维护事件,则包含一个 JSON 字符串,其中包含有关事件的信息。有关更多信息,请参阅查看有关已完成或已取消的事件的事件历史记录 2018-08-17
events/maintenance/scheduled 如果实例存在活动的维护事件,则包含一个 JSON 字符串,其中包含有关事件的信息。有关更多信息,请参阅查看计划的事件 2018-08-17
hostname 实例的私有 IPv4 DNS 主机名。在存在多个网络接口的情况下,其指的是 eth0 设备 (设备号为 0 的设备)。 1.0
iam/info 如果存在与实例关联的 IAM 角色,则包含有关实例配置文件上次更新时间的信息 (包括实例的 LastUpdated 日期、InstanceProfileArn 和 InstanceProfileId)。如果没有,则不显示。 2012-01-12
iam/security-credentials/role-name 如果存在与实例关联的 IAM 角色,则 role-name 为角色的名称,并且 role-name 包含与角色关联的临时安全凭证 (有关更多信息,请参阅 通过实例元数据检索安全凭证)。如果没有,则不显示。 2012-01-12
identity-credentials/ec2/info [仅供内部使用] AWS 用于向 Amazon EC2 基础设施的其余部分标识实例的凭据的相关信息。 2018-05-23
identity-credentials/ec2/security-credentials/ec2-instance [仅供内部使用] AWS 用于向 Amazon EC2 基础设施的其余部分标识实例的凭据。 2018-05-23
instance-action 通知实例在准备打包时重新启动。有效值:none | shutdown | bundle-pending 2008-09-01
instance-id 此实例的 ID。 1.0
instance-type 实例的类型。有关更多信息,请参阅 实例类型 2007-08-29
kernel-id 此实例启动的内核的 ID,如果适用的话。 2008-02-01
local-hostname 实例的私有 IPv4 DNS 主机名。在存在多个网络接口的情况下,其指的是 eth0 设备 (设备号为 0 的设备)。 2007-01-19
local-ipv4 实例的私有 IPv4 地址。在存在多个网络接口的情况下,其指的是 eth0 设备 (设备号为 0 的设备)。 1.0
mac 实例的媒体访问控制 (MAC) 地址。在存在多个网络接口的情况下,其指的是 eth0 设备 (设备号为 0 的设备)。 2011 年 1 月 1 日
metrics/vhostmd 不再可用。 2011-05-01
network/interfaces/macs/mac/device-number 与该接口关联的唯一设备号。设备号与设备名称对应;例如,device-number 为 2 对应于 eth2 设备。此类别对应的是 AWS CLI 的 Amazon EC2 API 和 EC2 命令使用的 DeviceIndexdevice-index 字段。 2011 年 1 月 1 日
network/interfaces/macs/mac/interface-id 网络接口的 ID。 2011 年 1 月 1 日
network/interfaces/macs/mac/ipv4-associations/public-ip 与每个公用 IP 地址相关联并被分配到该接口的私有 IPv4 地址。 2011 年 1 月 1 日
network/interfaces/macs/mac/ipv6s 与接口关联的 IPv6 地址。仅对启动至 VPC 的实例返回。 2016-06-30
network/interfaces/macs/mac/local-hostname 实例的本地主机名称。 2011 年 1 月 1 日
network/interfaces/macs/mac/local-ipv4s 与接口关联的私有 IPv4 地址。 2011 年 1 月 1 日
network/interfaces/macs/mac/mac 该实例的 MAC 地址。 2011 年 1 月 1 日
network/interfaces/macs/mac/owner-id 网络接口拥有者的 ID。在多个接口的环境中,接口可由第三方连接,如 Elastic Load Balancing。接口拥有者需为接口上的流量付费。 2011 年 1 月 1 日
network/interfaces/macs/mac/public-hostname 接口的公有 DNS (IPv4)。仅当 enableDnsHostnames 属性设置为 true 时,才返回此类别。有关更多信息,请参阅在您的 VPC 中使用 DNS 2011 年 1 月 1 日
network/interfaces/macs/mac/public-ipv4s 与接口关联的公有 IP 地址或弹性 IP 地址。一个实例上可能有多个 IPv4 地址。 2011 年 1 月 1 日
network/interfaces/macs/mac/security-groups 网络接口所属的安全组。 2011 年 1 月 1 日
network/interfaces/macs/mac/security-group-ids 网络接口所属的安全组的 ID。 2011 年 1 月 1 日
network/interfaces/macs/mac/subnet-id 接口所驻留的子网的 ID。 2011 年 1 月 1 日
network/interfaces/macs/mac/subnet-ipv4-cidr-block 接口所在子网的 IPv4 CIDR 块。 2011 年 1 月 1 日
network/interfaces/macs/mac/subnet-ipv6-cidr-blocks 接口所在子网的 IPv6 CIDR 块。 2016-06-30
network/interfaces/macs/mac/vpc-id 接口所驻留的 VPC 的 ID。 2011 年 1 月 1 日
network/interfaces/macs/mac/vpc-ipv4-cidr-block VPC 的主 IPv4 CIDR 块。 2011 年 1 月 1 日
network/interfaces/macs/mac/vpc-ipv4-cidr-blocks VPC 的 IPv4 CIDR 块。 2016-06-30
network/interfaces/macs/mac/vpc-ipv6-cidr-blocks 接口所在 VPC 的 IPv6 CIDR 块。 2016-06-30
placement/availability-zone 实例启动的可用区。 2008-02-01
product-codes 与实例关联的 AWS Marketplace 产品代码(如果有)。 2007-03-01
public-hostname 实例的公有 DNS。仅当 enableDnsHostnames 属性设置为 true 时,才返回此类别。有关更多信息,请参阅 Amazon VPC 用户指南中的在您的 VPC 中使用 DNS 2007-01-19
public-ipv4 公有 IPv4 地址。如果弹性 IP 地址与实例相关联,返回的值是弹性 IP 地址。 2007-01-19
public-keys/0/openssh-key 公有密钥。仅在实例启动时提供了公有密钥的情况下可用。 1.0
ramdisk-id 启动时指定的 RAM 磁盘 的 ID,如果适用的话。 2007-10-10
reservation-id 预留的 ID。 1.0
security-groups

应用到实例的安全组的名称。

在启动后,您可以更改实例的安全组。这些更改将体现在此处和 network/interfaces/macs/mac/security-groups 中。

1.0
services/domain

区域的 AWS 资源所在的域。

2014-02-25
services/partition

资源所处的分区。对于标准 AWS 区域,分区是 aws。如果资源位于其他分区,则分区是 aws-partitionname。例如,中国(北京)区域中的资源的分区为 aws-cn

2015-10-20
spot/instance-action

操作(休眠、停止或终止)和操作发生的大致时间(用 UTC 表示)。仅在已将 Spot 实例 实例标记为休眠、停止或终止时才提供此项目。有关更多信息,请参阅instance-action

2016-11-15
spot/termination-time

Spot 实例 操作系统将收到关闭信号的大致时间 (UTC)。仅当 Spot 实例 已由 Amazon EC2 标记为终止时,此项目才会出现并包含时间值(例如,2015-01-05T18:02:00Z)。如果您自己终止了 Spot 实例,那么终止时间项目不会设置为时间。有关更多信息,请参阅termination-time

2014-11-05

动态数据类别

下表列举了动态数据的类别。

数据 描述 引入的版本
fws/instance-monitoring 显示客户是否在 CloudWatch 中启用了详细的一分钟监控的值。有效值:enabled | disabled 2009-04-04
instance-identity/document 包含实例属性 (如实例 ID、私有 IP 地址等) 的 JSON。请参阅 实例身份文档 2009-04-04
instance-identity/pkcs7 用于验证签名的文档的真实性和内容。请参阅 实例身份文档 2009-04-04
instance-identity/signature 可被其他各方用于验证来源和真实性的数据。请参阅 实例身份文档 2009-04-04