检索实例元数据 - Amazon Elastic Compute Cloud

检索实例元数据

由于您的正在运行的实例存在实例元数据,因此您无需使用 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 等工具,如以下示例中所示。

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/

您也可以下载实例元数据查询工具,通过该工具,您无需输入完整的 URI 或目录名称就可以使用 实例元数据服务版本 1 查询实例元数据。

响应和错误消息

所有实例元数据以文本形式返回(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 版本相关联。如果您有依赖于以前版本中所存在的结构和信息的脚本,则您可使用早期版本。

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

获取顶级元数据项

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

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/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ events/ 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
[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 请求使用在前面的示例命令中创建和存储的令牌,并假设该令牌尚未过期。

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

 

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

 

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

 

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

获取可用的公有密钥列表

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

IMDSv2
[ec2-user ~]$ `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/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 的格式。

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/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 密钥格式)。

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/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。

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/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 默认为第一个匹配规则。