首页 文章

无法从EC2访问具有IAM角色的S3文件

提问于
浏览
1

我创建了一个IAM角色'test'并分配给EC2实例 . 我创建了一个带有存储桶策略的S3存储桶

{
    "Version": "2012-10-17",
    "Id": "Policy1475837721706",
    "Statement": [
        {
            "Sid": "Stmt1475837720370",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::770370070203:role/test"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::test-role-123/*"
        }
    ]
}

从EC2开始,我通过发送curl请求从此_1537678获得了AccessKey和SecretKey

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>

使用上面的响应,我编写了一个节点脚本来向存储桶中的资源发出请求

var AWS = require('aws-sdk');

var d = {
    "Code" : "Success",
    "LastUpdated" : "2016-10-07T12:28:09Z",
    "Type" : "AWS-HMAC",
    "AccessKeyId" : "ASIAIMJBHYLH6GWOWNMQ",
    "SecretAccessKey" : "7V/k5nvFdhXOcT+nhYjGqHM4QmUWjNBUM1ERJQJs",
    "Token" : "FQoDYXdzEO7//////////wEaDGG+SgxD4Es4Z1RBZCKzAz855JuKfm8s7LDcP5T9TGvDdJELsYTzPi47HJ9Q5oaK8OTb0Us0RjvpGW278Mb1gg1dNip1VD2N/GW5/1TFC6xhNpnnZ9+LNkJAwVVZg5raGM91k56X/VOA++/5WivSpO4jWg8fZDibivVyHuoMJJTkurFtEXrweDOCqpiabypTCc5jFtX8NfQuHubwl4C1jp2pMasVS1jwhjU72TA8Pn9EsIIvh8JXDC1dVfppwnslolAeJyOOAHdL1AQSs3nI6IvPCtKhBjtDaVuoiH/lHrnKrw6AeMHoTYQay4wOYRnE4ffngtksekZEULXvERWE4NCs3leXGMqrdzOr8xdZ9m0j3IkshqSS56fkq6E9JtLhSVGyy44ELrL7kYW/dpHE03V+dwQPXMhRafjsVsPD7sUnBfH/+4yyL0VDX1vlFRKbRi50i/Eqvxsb9bcSTsE0W5yWmOWR8reTTYWcWyQXGvxKVYVxLWZKVRfmNfx6IX2sqan7e7pjCtUrqXB1TBMpXdy8KSH9qoJtNAQTYBXws7oFLYY+F2esnNCma0bdNcCeAQ6t/6aPfUdpdLgv8BcGciZxayiqqd6/BQ==",
    "Expiration" : "2016-10-07T18:51:57Z"
};
AWS.config.accessKeyId = d.AccessKeyId;
AWS.config.secretAccessKey = d.SecretAccessKey;
var s3params = {Key: "test.json", Bucket:"test-role-123"};
AWS.config.region = 'ap-south-1';

var s3 = new AWS.S3();

s3.getSignedUrl('getObject', s3params, function(err, url) {
    console.log(url);
});

在运行此代码时,我收到了签名的URL . 但是这会产生InvalidAccessKeyId错误 . 我怀疑s3存储桶策略是否错误,因此尝试使用IAM用户凭据获得类似的策略 . 它完全有效 .

欢迎任何提示或建议 .

1 回答

  • 3

    有三点需要注意:

    • 如何从Amazon EC2实例提供和访问 credentials

    • 如何分配 permissions 以访问Amazon S3

    • 如何 Pre-Signed URLs 功能

    1. How credentials are provided and accessed from an Amazon EC2 instance

    当使用IAM角色启动Amazon EC2实例时,Instance Metadata会自动提供由访问密钥,密钥和令牌组成的 temporary access credentials . 这些凭据大约每六个小时轮换一次 .

    任何使用AWS SDK的代码(例如Python,Java,PHP)都知道如何自动检索这些凭据 . 因此,在使用IAM角色 does not require you to retrieve nor provide access credentials 启动的Amazon EC2实例上运行的代码 - 它只是自动运行!

    因此,在上面的代码示例中,您可以 remove any lines that specifically refer to credentials . 您的工作只是确保IAM角色对您希望执行的操作具有足够的权限 .

    这也适用于AWS Command-Line Interface (CLI),它实际上只是一个提供对AWS API调用的命令行访问的Python程序 . 由于它使用适用于Python的AWS开发工具包,因此它会自动从实例元数据中检索凭据,并且在从使用IAM角色启动的Amazon EC2实例中使用时不需要凭据 .

    2. How to assign permissions for access to Amazon S3

    Amazon S3中的对象为 private by default . 分配访问对象的权限有三种方法:

    • Object ACLs (访问控制列表):这些是对象本身的权限

    • Bucket Policies: 这是一组应用于存储桶的规则,但它也可以指定与存储桶子集相关的权限(例如存储桶中的特定路径)
      适用于IAM用户,组或角色的

    • IAM Policies :这些权限专门适用于这些实体

    由于您希望将Amazon S3对象的访问权限授予特定的IAM用户,因此最好通过附加到该用户的 IAM Policy 分配权限,而不是成为 Bucket Policy 的一部分 .

    因此,你应该:

    • 删除Bucket Policy

    • 在IAM中创建 Inline Policy 并将其附加到所需的IAM用户 . 该政策适用于该用户,不需要委托人

    这是一个示例政策:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Stmt1",
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject"
                ],
                "Resource": [
                    "arn:aws:s3:::MY-BUCKET/*"
                ]
            }
        ]
    }
    

    我推荐了 Inline Policy ,因为此政策仅适用于一个用户 . 如果要为许多用户分配权限,建议将策略附加到 IAM Group ,然后分配给该组的用户将继承权限 . 或者,创建IAM策略,然后将该策略附加到所有相关用户 .

    3. How Pre-Signed URLs function

    Amazon S3 Pre-Signed URLs 是一种授予对Amazon S3对象的临时访问权限的方法 . 生成的URL包括:

    • 有权访问该对象的IAM用户的 Access Key

    • expiration time

    • A signature 通过授权URL的has操作创建

    要实现的关键点与生成预签名URL时使用的权限有关 . 如Amazon S3文档中所述Share an Object with Others

    拥有有效安全凭据的任何人都可以创建预签名URL . 但是,为了成功访问对象,必须由有权执行预签名URL所基于的操作的人创建预签名URL .

    这意味着生成预签名URL时使用的凭据也是用作预签名URL一部分的凭据 . 当然,与这些凭证关联的实体需要访问该对象的权限 - 预签名URL仅仅是在临时期间授予对对象访问权的手段 .

    这也意味着,就你的例子而言, you do not need to create a specific role for granting access to the object(s) in Amazon S3 . 相反,您可以在Amazon EC2实例中使用更宽松的IAM角色(例如,也可以将对象上传到S3),但是当它生成预签名URL时,它只授予对该对象的临时访问权限(而不是其他权限,例如上传权限) .

    如果您的Amazon EC2实例上运行的软件仅与AWS交互以创建签名URL,那么仅具有 GetObject 权限的您的角色就可以了 . 但是,如果您的实例想要执行更多操作,则创建一个角色,该角色授予实例适当的权限(包括对S3的 GetObject 访问权限)并使用该角色生成签名URL .

    如果您希望练习生成签名URL,则最新版本的AWS Command-Line Interface (CLI)包含一个可以生成预签名URL的 aws s3 presign s3://path 命令 . 尝试使用各种 --profile 设置来查看它如何与不同的IAM用户一起使用 .

相关问题