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

如何解决EC2实例访问元数据时出现的401未授权错误?

解决EC2实例元数据访问401 Unauthorized问题

问题根源

你尝试通过修改/etc/nitro/eni.cfg禁用IMDSv2,但该配置修改后不会立即生效,需要重启实例或nitro网络服务才能加载新配置。而你的UserData脚本在修改文件后立刻执行curl,此时IMDSv2仍处于启用状态,导致401错误。此外,直接修改系统文件并非AWS官方推荐的IMDS配置方式,存在持久化失效风险。

推荐解决方案

方案1:创建实例时直接配置元数据选项(最优)

在调用create_instances时添加MetadataOptions参数,设置允许IMDSv1访问,无需修改系统文件:

import boto3
import webbrowser
import time

ec2 = boto3.resource('ec2')

myInstance = ec2.create_instances(
    ImageId='ami-0f34c5ae932e6f0e4',
    KeyName='mykey',
    MinCount=1,
    MaxCount=1,
    SecurityGroupIds=['sg-070cacabf704f07ef'],
    InstanceType='t2.nano',
    # 添加元数据配置,允许IMDSv1和IMDSv2
    MetadataOptions={
        'HttpTokens': 'optional',
        'HttpPutResponseHopLimit': 1
    },
    UserData=f"""#!/bin/bash
yum update -y
yum install httpd -y
systemctl enable httpd
systemctl start httpd

# 直接用IMDSv1获取元数据,无需修改系统文件
instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
ami_id=$(curl -s http://169.254.169.254/latest/meta-data/ami-id)
instance_type=$(curl -s http://169.254.169.254/latest/meta-data/instance-type)

cat > /var/www/html/index.html <<EOF
<!DOCTYPE html>
<html>
<head>
    <title>Instance Metadata</title>
</head>
<body>
    <h1>Hello World</h1>
    <p>Instance ID: $instance_id</p>
    <p>AMI ID: $ami_id</p>
    <p>Instance Type: $instance_type</p>
</body>
</html>
EOF
    """,
    TagSpecifications=[
        {
            'ResourceType': 'instance',
            'Tags': [
                {
                    'Key': 'Name',
                    'Value': 'MyInstance'
                }
            ]
        }
    ]
)

# 后续代码不变
myInstance[0].wait_until_running()
myInstance[0].reload()

instance_id = myInstance[0].id
image_id = myInstance[0].image_id
instance_type = myInstance[0].instance_type

time.sleep(30)

public_ip = myInstance[0].public_ip_address

print('Instance ID:', instance_id)
print('Public IP Address:', public_ip)

webbrowser.open_new_tab(f'http://{public_ip}/')

print('Opened web browser')

方案2:使用IMDSv2协议获取元数据(无需禁用v2)

如果不想修改实例元数据配置,可在UserData中使用IMDSv2的token方式访问:

# 获取IMDSv2 token
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# 通过token访问元数据
instance_id=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/instance-id)
ami_id=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/ami-id)
instance_type=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/instance-type)

为什么修改/etc/nitro/eni.cfg无效?

/etc/nitro/eni.cfg是Nitro实例的网络配置文件,修改后需要重启nitro-enimgr服务或实例才能生效:

systemctl restart nitro-enimgr

但在UserData中执行该操作会中断网络,导致后续脚本无法完成,因此这种方式不适用初始化场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:10:55