You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java获取AWS EC2实例公网IP时返回401错误的问题

问题解答

获取EC2实例公网IP的IMDS元数据路径不会随AWS区域变化,http://169.254.169.254/latest/meta-data/public-ipv4是全局统一的。你遇到的401错误和区域无关,核心原因是IMDSv2强制要求先获取会话令牌(Session Token),才能访问元数据接口,而你的代码直接跳过了令牌获取步骤。

问题根源

  • 你在eu-central区域的实例可能允许IMDSv1回退(默认配置可能未强制IMDSv2),所以直接访问能成功;
  • ap-south区域的实例大概率被配置为强制启用IMDSv2(禁止IMDSv1访问),因此无令牌的请求会被拒绝,返回401 Unauthorized。

正确的IMDSv2实现代码

使用IMDSv2访问元数据需要两步:先发送PUT请求获取会话令牌,再携带令牌访问目标元数据接口。以下是适配你的场景的Java实现:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class EC2MetadataUtils {
    private static final String IMDS_BASE_URL = "http://169.254.169.254/latest/meta-data/";
    private static final String TOKEN_URL = "http://169.254.169.254/latest/api/token";
    private static final int TOKEN_TTL = 21600; // 令牌有效期,最长6小时

    public String findCurrentPublicIp() throws IOException {
        // 第一步:获取IMDSv2会话令牌
        String token = getIMDSv2Token();
        
        // 第二步:携带令牌访问公网IP元数据
        URL publicIpUrl = new URL(IMDS_BASE_URL + "public-ipv4");
        HttpURLConnection connection = (HttpURLConnection) publicIpUrl.openConnection();
        connection.setRequestProperty("X-aws-ec2-metadata-token", token);
        
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
            return reader.readLine();
        } finally {
            connection.disconnect();
        }
    }

    private String getIMDSv2Token() throws IOException {
        URL tokenUrl = new URL(TOKEN_URL);
        HttpURLConnection connection = (HttpURLConnection) tokenUrl.openConnection();
        connection.setRequestMethod("PUT");
        connection.setRequestProperty("X-aws-ec2-metadata-token-ttl-seconds", String.valueOf(TOKEN_TTL));
        
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
            return reader.readLine();
        } finally {
            connection.disconnect();
        }
    }
}

额外排查点

  1. 检查CloudFormation模板中EC2实例的MetadataOptions配置:确认ap-south区域的实例是否设置了HttpTokens: required(强制IMDSv2),而eu-central区域可能是optional(允许IMDSv1)。示例CloudFormation片段:
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      # 其他配置...
      MetadataOptions:
        HttpTokens: required # 强制IMDSv2,会拒绝无令牌请求
        HttpPutResponseHopLimit: 1
  1. 确保你的IMDSv2客户端版本(imds-2.20.11.jar)配置正确,或者直接使用上述原生实现避免依赖问题。

内容的提问来源于stack exchange,提问作者slow_learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 21:32:14