使用 IMDSv2
您可以使用以下其中一种方法,从正在运行的实例中访问实例元数据:
-
实例元数据服务版本 1 (IMDSv1) – 一种请求/响应方法
-
实例元数据服务版本 2 (IMDSv2) – 一种面向会话的方法
-
为了将 EC2Launch 与 IMDSv2 一起使用,版本必须为 1.3.2002730 或更高版本。
默认情况下,您可以使用 IMDSv1 和/或 IMDSv2。实例元数据服务根据以下条件区分 IMDSv1 和 IMDSv2 请求:对于任何给定请求,PUT
或 GET
标头(对于 IMDSv2 是唯一的)在该请求中是否存在。有关更多信息,请参阅借助 EC2 实例元数据服务的增强功能,为开放式防火墙、反向代理和 SSRF 漏洞增加深度防御
您可以在每个实例上配置实例元数据服务,以便本地代码或用户必须使用 IMDSv2。在指定必须使用 IMDSv2 时,IMDSv1 不再起作用。有关更多信息,请参阅配置实例元数据选项。
要检索实例元数据,请参阅检索实例元数据。
此部分中的示例使用实例元数据服务的 IPv4 地址:169.254.169.254
。如果要通过 IPv6 地址检索 EC2 实例的实例元数据,请确保启用并改用 IPv6 地址:fd00:ec2::254
。实例元数据服务的 IPv6 地址与 IMDSv2 命令兼容。IPv6 地址仅可在 基于 Nitro 系统构建的实例 上访问。
实例元数据服务版本 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"`
然后,通过令牌使用以下命令生成顶级元数据项。
[ec2-user ~]$
curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/
组合命令
您可以存储令牌并组合命令。以下示例将上述两个命令组合在一起,并将会话令牌标头存储在名为 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 请求实例元数据时,请求必须包含以下内容:
-
使用
PUT
请求启动到实例元数据服务的会话。PUT
请求返回一个令牌,该令牌必须包含在对实例元数据服务的后续GET
请求中。需要具有该令牌才能使用 IMDSv2 访问元数据。 -
将该令牌包含在对实例元数据服务的所有
GET
请求中。如果将令牌使用设置为required
,没有有效令牌或令牌过期的请求将显示401 - Unauthorized
HTTP 错误代码。有关更改令牌使用要求的信息,请参阅 Amazon CLI Command Reference 中的 modify-instance-metadata-options。-
令牌是实例特定的密钥。令牌在其他 EC2 实例上无效,如果尝试在生成令牌的实例外部使用,令牌将会被拒绝。
-
PUT
请求必须包含一个标头,它以秒为单位指定令牌的生存时间 (TTL),最多为 6 小时(21600 秒)。令牌表示一个逻辑会话。TTL 指定令牌的有效时间长度,因而指定会话的持续时间。 -
在令牌过期后,要继续访问实例元数据,您必须使用另一
PUT
创建新会话。 -
您可以选择在每个请求中重复使用令牌或创建新的令牌。对于少量请求,在每次需要访问实例元数据服务时生成并立即使用令牌可能更方便。但为了提高效率,您可以为令牌指定更长的持续时间并重复使用令牌,而不必在每次需要请求实例元数据时都编写
PUT
请求。对并发令牌数量没有实际限制,每个令牌表示自己的会话。不过,IMDSv2 仍然受到正常实例元数据服务连接和限制的制约。有关更多信息,请参阅查询限制。
-
允许在 IMDSv2 实例元数据请求中使用 HTTP GET
和 HEAD
方法。如果 PUT
请求包含 X-Forwarded-For 标头,则会被拒绝。
默认情况下,PUT
请求的响应在 IP 协议级别的响应跃点数限制(生存时间)为 1
。如果需要增大跃点数限制,您可以使用 modify-instance-metadata-options
命令进行调整。例如,您可能需要使用更大的跃点数限制,以便与实例上运行的容器服务保持向后兼容。有关更多信息,请参阅 Amazon CLI Command Reference 中的 modify-instance-metadata-options。
转换为使用 实例元数据服务版本 2
使用实例元数据服务版本 2 (IMDSv2) 为可选项。将继续无期限支持实例元数据服务版本 1 (IMDSv1)。如果您选择迁移以使用 IMDSv2,我们建议您使用以下工具和转换途径。
帮助转换为 IMDSv2 的工具
如果您的软件使用 IMDSv1,请使用以下工具帮助重新配置软件,以使用 IMDSv2。
-
Amazon软件:最新版本的Amazon开发工具包和 CLI 支持 IMDSv2。要使用 IMDSv2,请确保 EC2 实例具有最新版本的Amazon开发工具包和 CLI。有关更新 CLI 的信息,请参阅 Amazon Command Line Interface 用户指南中的安装、更新和卸载 Amazon CLI。
-
CloudWatch:IMDSv2 使用支持令牌的会话,而 IMDSv1 不使用。
MetadataNoToken
CloudWatch 指标跟踪对使用 IMDSv1 的实例元数据服务的调用次数。通过查看该指标是否为零,您可以确定是否以及何时将所有软件升级为使用 IMDSv2。有关更多信息,请参阅实例指标。 -
EC2 API 和 CLI 更新:对于现有实例,您可以使用 modify-instance-metadata-options CLI 命令(或 ModifyInstanceMetadataOptions API)以要求使用 IMDSv2。对于新实例,您可以使用 run-instances CLI 命令(或 RunInstances API)和
metadata-options
参数以启动要求使用 IMDSv2 的新实例。为了要求在 Auto Scaling 组启动的所有新实例上使用 IMDSv2,您的 Auto Scaling 组可以使用启动模板或启动配置。当您创建启动模板或创建启动配置时,必须配置
MetadataOptions
参数以要求使用 IMDSv2。在您配置启动模板或启动配置后,Auto Scaling 组会使用新的启动模板或启动配置启动新实例,但现有实例不受影响。使用 modify-instance-metadata-options CLI 命令(或 ModifyInstanceMetadataOptions API)以要求在现有实例上使用 IMDSv2,或者终止这些实例,这时 Auto Scaling 组会使用在启动模板或启动配置中定义的实例元数据选项设置启动新的替换实例。
-
IAM 策略和 SCP:您可以使用 IAM 条件强制要求,除非实例使用 IMDSv2,否则,IAM 用户不能启动实例。您也可以使用 IAM 条件强制要求 IAM 用户不能修改正在运行的实例以重新启用 IMDSv1,以及强制要求在实例上提供实例元数据服务。
可以使用
ec2:MetadataHttpTokens
、ec2:MetadataHttpPutResponseHopLimit
和ec2:MetadataHttpEndpoint
IAM 条件键来控制对 RunInstances 和 ModifyInstanceMetadataOptions API 以及相应 CLI 的使用。如果创建了策略,并且 API 调用中的参数与使用条件键的策略中指定的状态不匹配,API 或 CLI 调用将失败并显示UnauthorizedOperation
响应。可以在 IAM 策略或 Amazon Organizations 服务控制策略 (SCP) 中使用这些条件键。此外,您还可以选择额外的保护层以强制从 IMDSv1 更改为 IMDSv2。在与通过 EC2 角色凭证调用的 API 相关的访问管理层上,您可以在 IAM 策略或 Amazon Organizations 服务控制策略 (SCP) 中使用新的条件键。具体来说,通过在 IAM 策略中使用值为
ec2:RoleDelivery
的策略条件键2.0
,使用从 IMDSv1 获取的 EC2 角色凭证进行的 API 调用将收到UnauthorizedOperation
响应。通过使用 SCP 所需的该条件,可以更广泛地实现相同的效果。这会确保通过 IMDSv1 提供的凭证不能实际用于调用 API,因为任何不符合指定条件的 API 调用将会收到UnauthorizedOperation
错误。有关示例 IAM 策略,请参阅 使用实例元数据。有关更多信息,请参阅 Amazon Organizations 用户指南中的服务控制策略。
要求 IMDSv2 访问的建议途径
在使用上述工具时,我们建议您按照以下途径转换为 IMDSv2:
步骤 1:在开始时
将在 EC2 实例上使用角色凭证的开发工具包、CLI 和软件更新为与 IMDSv2 兼容的版本。有关更新 CLI 的信息,请参阅 Amazon Command Line Interface 用户指南中的升级到最新版本的 Amazon CLI。
然后,使用 IMDSv2 请求更改直接访问实例元数据的软件(换句话说,不使用开发工具包)。
步骤 2:在转换期间
使用 CloudWatch 指标 MetadataNoToken
跟踪您的转换进度。此指标显示对在实例上使用 IMDSv1 的实例元数据服务的调用次数。有关更多信息,请参阅实例指标。
步骤 3:在所有实例上一切准备就绪时
在 CloudWatch 指标 MetadataNoToken
记录 IMDSv1 使用次数为零时,说明在所有实例上一切准备就绪。在此阶段,您可以执行以下操作:
-
对于现有实例:您可以通过 modify-instance-metadata-options 命令要求使用 IMDSv2。您可以在正在运行的实例上进行这些更改,而无需重新启动实例。
-
对于新实例:启动新实例时,您可以执行以下操作之一:
-
在 Amazon EC2 控制台启动实例向导中,将可访问的元数据设置为已启用,将元数据版本设置为 V2。有关更多信息,请参阅步骤 3:配置实例详细信息。
-
使用 run-instances 命令指定仅使用 IMDSv2。
-
更新现有实例的实例元数据选项的操作只能通过 API 或 Amazon CLI 执行。Amazon EC2 控制台当前不支持此操作。有关更多信息,请参阅配置实例元数据选项。
步骤 4:将所有实例转换为 IMDSv2 时
可以使用 ec2:MetadataHttpTokens
、ec2:MetadataHttpPutResponseHopLimit
和 ec2:MetadataHttpEndpoint
IAM 条件键来控制对 RunInstances 和 ModifyInstanceMetadataOptions API 以及相应 CLI 的使用。如果创建了策略,并且 API 调用中的参数与使用条件键的策略中指定的状态不匹配,API 或 CLI 调用将失败并显示 UnauthorizedOperation
响应。有关示例 IAM 策略,请参阅 使用实例元数据。