AWS IMDSv2区域级强制实施:提升云安全新特性

本文详细介绍了AWS新推出的区域级IMDSv2强制实施功能,包括其安全背景、演进历程、API调用方法及Terraform支持,帮助用户防范SSRF漏洞攻击,提升云环境安全性。

IMDSv2强制实施:即将登陆您所在的区域!

2025年1月8日 / 2024年3月28日

3月25日,AWS发布了一项新功能,可默认在区域级别对新启动的实例强制实施IMDSv2。这代表了一项期待已久的功能,但仍存在一些注意事项。

IMDSv2简介

IMDSv2是AWS于2019年11月发布的安全机制,紧随备受关注的Capital One数据泄露事件。该事件由类似SSRF的漏洞引发,导致美国参议员Ron Wyden致信AWS,询问为客户提供了哪些保护措施。以下是我从这封信中摘录的几段内容:

“许多安全专家公开推测,Capital One黑客利用了SSRF漏洞,这是专家多年来一直警告的缺陷。据亚马逊所知,是否使用了SSRF攻击来获取Capital One的客户数据?”

“在过去两年中,有多少亚马逊客户因其亚马逊云计算服务器遭受SSRF攻击而受到损害?”

“亚马逊是否向其云计算客户提供了关于SSRF攻击可能性的任何指导,特别是针对亚马逊元数据服务(…)?”

有趣的是,“利用SSRF漏洞滥用AWS元数据服务”是我在2017年写的第一篇安全主题博客文章,甚至在我开始从事安全工作之前。Jon Hencinski和Scott Piper在2018年和2019年也对此发出过警告:

当强制实施时,IMDSv2可以防范SSRF漏洞,否则攻击者可能通过这些漏洞从实例元数据服务(IMDS)泄露凭据。

2022年底和2021年底的过往研究表明,此类漏洞是公开记录的云安全事件最常见的原因之一。因此,IMDSv2被视为在AWS环境中必须实施的关键云安全控制措施。

关于IMDSv2的更深入解释,请参阅出色的Nick Frichette(恰巧是我的同事)撰写的《保护EC2实例元数据服务》。我也在我的演讲“Fantastic AWS Hacks and Where to Find Them”中讨论过它。

发展历程

到目前为止,强制实施IMDSv2相对繁琐。

最初,您必须在实例级别通过设置实例本身或关联的EC2启动模板或启动配置上的metadata_options.http_tokens="required"选项来强制执行。虽然您可以使用ec2:MetadataHttpTokens条件键限制ec2:RunInstances的能力,仅允许使用强制IMDSv2的实例,但这仍然是一个非常手动的过程,并且是不安全默认设置的典型例子。

2022年10月,AWS发布了一项新功能,允许我们声明“默认情况下,对从此特定AMI启动的所有实例强制实施IMDSv2”。

1
2
3
4
5
6
aws ec2 register-image \
    --name my-image \
    --root-device-name /dev/xvda \
    --block-device-mappings DeviceName=/dev/xvda,Ebs={SnapshotId=snap-0123456789example} \
    --architecture x86_64 \
    --imds-support v2.0

这方便地在2023年3月推出了默认强制IMDSv2的Amazon Linux 2023 AMI。由于发布时未包含Terraform支持,我借此机会向Terraform AWS提供商提交了我的第一个(小)贡献。

2023年11月,AWS控制台UI开始在最流行的“快速启动”EC2屏幕中默认强制实施IMDSv2。

现在,2024年3月,AWS引入了这项新功能,允许默认在区域中为所有新实例强制实施IMDSv2!

但历史就说到这里——让我们看看这个功能是如何工作的。

认识GetInstanceMetadataDefaults和ModifyInstanceMetadataDefaults

这两个新的API调用于3月25日出现在我的RSS订阅源中,随后官方公告也发布了。顾名思义,这两个新功能允许您在区域级别设置默认的EC2实例元数据选项。并不完全是文档中建议的“账户级别”,因为它是一个区域设置。

1
2
3
4
5
6
7
client.modify_instance_metadata_defaults(
    HttpTokens='optional'|'required'|'no-preference',
    HttpPutResponseHopLimit=123,
    HttpEndpoint='disabled'|'enabled'|'no-preference',
    InstanceMetadataTags='disabled'|'enabled'|'no-preference',
    DryRun=True|False
)

这里重要的部分是HttpTokens。将其设置为required意味着“强制实施IMDSv2”。因此,下面的代码是您希望在所有账户和区域中运行的:

1
2
3
4
import boto3

ec2_client = boto3.client('ec2')
ec2_client.modify_instance_metadata_defaults(HttpTokens='required')

在撰写本文时,AWS CLI尚未支持这些API调用,因此您必须使用可靠的Python或其他SDK。

更新:AWS CLI在1.32.70版(3月25日发布)和2.15.33版(3月27日发布)中增加了支持:

1
aws ec2 modify-instance-metadata-defaults --http-tokens required

如果您关注了前面的“历史”部分,您可能已经注意到我们现在可以在区域、AMI和实例级别设置IMDS。这些设置如何相互作用?AWS提供了一份非常清晰的文档,可以总结为“实例设置优先(如果已设置),区域设置其次(如果已设置),AMI设置第三(如果已设置),默认不强制IMDSv2”。

实现Terraform支持

任何没有IaC支持的云功能对于每天处理大量区域和账户的从业者来说,其帮助都是有限的。

作为一名重度Terraform用户,我确保在一个问题中跟踪这个需求,并很快鼓起勇气自己实现这个新的Terraform资源,使用了有用的HashiCorp贡献者指南。

经过几个小时的痛苦调试Go代码和与CI斗争,拉取请求准备好了。它现在已被合并并在v5.43.0中发布。您现在可以使用aws_ec2_instance_metadata_defaults资源:

1
2
3
4
5
6
resource "aws_ec2_instance_metadata_defaults" "imdsv2" {
  http_tokens                 = "required" # non-default
  instance_metadata_tags      = "disabled"
  http_endpoint               = "enabled"
  http_put_response_hop_limit = 1
}

总结

这个新功能对于每天努力强制实施IMDSv2的从业者非常有用。这是在环境中启用安全默认设置的好方法——但默认情况下仍然留给我们不安全的默认设置。根据AWS的公告,这可能会很快改变:

2024年中 – 新发布的Amazon EC2实例类型将默认仅使用IMDSv2。为了过渡支持,您仍然能够在启动时或在实例运行时启用/打开IMDSv1,而无需重启或停止/启动。

同样重要的是要记住,这个功能是关于默认设置的。使用它来默认强制实施IMDSv2并不能阻止任何人启动允许使用IMDSv1的实例。为此,您可以使用SCP或使用ec2:MetadataHttpTokens条件键显式拒绝。

敬请关注,感谢阅读!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计