我创建了一个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 回答
有三点需要注意:
如何从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用户 . 该政策适用于该用户,不需要委托人
这是一个示例政策:
我推荐了 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仅仅是在临时期间授予对对象访问权的手段 .
这也意味着,就你的例子而言, 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用户一起使用 .