我开始使用AWS IAM instance roles,这对于提升我们的安全管理水平非常有用,但它增加了维护轻量级开发流程的一些挑战。
手头的问题是:
我定义了 AWS实例角色,并将安全策略附加到此角色。此策略指定为在此角色下启动的新EC2实例授予的权限,它是一个冗长且复杂的json文档,其规则如"允许访问S3存储桶x"并且"拒绝访问SQS y"。这在EC2上很有效。
接下来,我想让开发人员在本地开发我们的代码,在IDE中进行本地开发,并使用前面定义的完全相同的安全策略。当开发人员生成新代码时,这是非常重要的b / c我希望他们对它进行测试WRT与他们在生产中运行的完全相同的安全策略。如果他们使用不同的安全策略,那么事情就会失败。
问题在于我还没有办法做到这一点。可以定义IAM组,并将开发人员加入组(例如"开发人员"组)。在这个组中,我可以定义适用于该组中所有开发人员的IAM安全策略。但是,在实例角色的上下文中,没有办法(我发现)重用附加到组的策略。或者在组的上下文中使用附加到角色的策略。 (我完全错过了这个吗?...)
总而言之,我想要的是:1)定义安全政策文件一次。 2)在两个地方重用该文档,一个是IAM实例角色定义,另一个是IAM组。
无法这样做意味着我必须为每种类型的服务维护两份复杂的JSON文档(不受版本控制)(我们有很多这样的服务)和对于每个环境(例如阶段/产品)。我可以很容易地看到它如何成为维护噩梦。
到目前为止,我想出的最好的事情可能是将策略文档存储在磁盘上,在版本控制下,并编写一个使用aws api将策略文档上载到实例角色和组的工具。这有点麻烦,所以我希望有一点灵活性。
你对我有更好的建议吗?...谢谢!
答案 0 :(得分:2)
AWS刚刚推出Managed Policies for AWS Identity & Access Management,它提供了一种在IAM实体之间共享和维护IAM策略的全新方法,专门用于减少当前重复的信息和工作量:
随着AWS安装的规模和复杂性的增加,您可能会发现自己正在编辑多个权限文档,以便添加新权限或删除现有权限。审计和确认权限也比必要更困难。
安全博客文章An Easier Way to Manage Your Policies提供了更多详细信息。
到目前为止,我想出的最好的事情可能是将策略文档存储在磁盘上,在版本控制下,并编写一个使用aws api将策略文档上载到实例角色和组的工具。这有点麻烦,所以我希望有一点灵活性。
这样的工具已经存在,实际上是AWS自身和第三方服务的主要后盾技术 - 看看AWS CloudFormation,为开发人员和系统管理员提供了一种简便的方法创建和管理相关AWS资源的集合,以有序和可预测的方式配置和更新它们。
更具体地说,AWS::IAM::Policy资源将IAM策略与IAM用户,角色或组相关联:
{
"Type": "AWS::IAM::Policy",
"Properties": {
"Groups" : [ String, ... ],
"PolicyDocument" : JSON,
"PolicyName" : String,
"Roles" : [ String, ...
"Users" : [ String, ... ],
}
}
CloudFormation当然还有很多,它是一个非常强大的工具(见Getting Started with AWS CloudFormation)。
答案 1 :(得分:2)
感谢@Steffen指出CloudFormation,但我认为我找到了一个更适合我的解决方案。
AWS提供Security Token Service,其中包括允许您承担角色。
这正是我想要的,因为我想要定义一次角色(例如一组AWS权限),然后让AWS EC2实例自动承担此角色(易于执行)以及开发人员承担特定服务的角色他们正在发展。开发人员部分涉及更多,但我将粘贴一些Java代码,以显示如何在下面执行此操作。
首先,在定义角色时,您必须说明允许哪个主体承担此角色。您可以通过编辑角色的信任关系部分(位于AWS Web UI上角色的定义页面底部)来实现此目的。
例如,这里是一个信任关系文档,允许EC2实例承担此角色,以及我的域中的一些用户(替换your-service-id-number
和your-user@example.com
):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::your-service-id-number:user/your-user@example.com",
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
接下来是在本地开发中运行时承担此角色的Java代码:
此代码检查我是否在EC2实例上运行,如果是,则将承担实例的角色(或者其他,DefaultAWSCredentialsProviderChain
定义的任何内容,但在我的情况下,最佳实践是 - EC2实例角色)。如果在开发环境中运行,例如在EC2之外,它承担roleName
AWSCredentialsProvider getCredentialsProvider(String roleName) {
if (isRunningOnEc2()) {
return new DefaultAWSCredentialsProviderChain();
}
// If not running on EC2, then assume the role provided
final AWSCredentials longLivedCredentialsProvider = new DefaultAWSCredentialsProviderChain().getCredentials(); // user credentials provided by env variables for ex.
// The String roleArn is defined at the top of the Role page titled "Role ARN" ;-)
final String roleArn = String.format("arn:aws:iam::your-service-id-number:role/%s", roleName);
final String roleSessionName = "session" + Math.random(); // not sure it's really needed but what the heck..
final STSAssumeRoleSessionCredentialsProvider credentialsProvider =
new STSAssumeRoleSessionCredentialsProvider(longLivedCredentialsProvider, roleArn, roleSessionName);
return credentialsProvider;
}
提供了实用程序isRunningOnEc2()
:
public static boolean isRunningOnEc2() {
try {
final InetAddress byName = InetAddress.getByName("instance-data");
return byName != null;
} catch (final UnknownHostException e) {
return false;
}
}
Steffen建议使用CloudFormation,在一般意义上也可能有用,主要是为了保持我的代码库和实际的AWS部署的一致性,但这是其他的东西。
虽然有一个令人讨厌的观点:可以将主体定义为实际用户名但不能定义为用户组,因此您实际上不能说#34;所有开发人员都可以承担角色x"但是相反,你必须具体列出每个开发人员。这很烦人,但我猜I'm not the only one with this complaint。