我有一个基于AWS的作业处理架构,需要EC2实例查询S3和SQS.为了使运行实例能够访问API,凭证将以base64编码的shell脚本的形式作为用户数据(-f)发送.例如:
$ cat ec2.sh ... export AWS_ACCOUNT_NUMBER='1111-1111-1111' export AWS_ACCESS_KEY_ID='0x0x0x0x0x0x0x0x0x0' ... $ zip -P 'secret-password' ec2.sh $ openssl enc -base64 -in ec2.zip
推出了许多实例......
$ ec2run ami-a83fabc0 -n 20 -f ec2.zip
每个实例使用'secret-password'对ec2.zip进行解码和解密,该密码被硬编码到init脚本中.虽然它确实有效,但我的方法有两个问题.
'zip -P'不是很安全
密码在实例中是硬编码的(它总是'秘密密码')
该方法与此处描述的方法非常相似
是否有更优雅或被接受的方法?使用gpg加密凭证并在实例上存储私钥来解密它是我现在正在考虑的一种方法,但我不知道任何警告.我可以直接使用AWS密钥对吗?我错过了一些非常明显的API部分吗?
您可以将凭据存储在计算机上(或传输,使用,然后删除它们.)
您可以通过安全通道传输凭据(例如,使用scp
非交互式身份验证,例如密钥对),这样您就不需要执行任何自定义加密(只需确保0400
在密钥文件中始终正确设置权限,例如,设置主文件的权限并使用scp -p
)
如果以上内容未回答您的问题,请提供更具体的详细信息.您的设置是什么以及您想要实现的目标.EC2操作是从中心位置在多个节点上启动的吗?SSH节点和中心位置之间是否可用?等等.
编辑
您是否考虑过参数化AMI,要求实例化您的AMI的人首先ec2-run-instances -f user-data-file
使用他们的AWS密钥填充用户数据()?然后,您的AMI可以动态检索这些每个实例的参数http://169.254.169.254/1.0/user-data
.
UPDATE
好的,这里对目前讨论的各种方法进行了安全性比较:
存储在未加密的AMI中的数据安全性user-data
低
明文数据是可访问的任何谁管理,以登录到AMI和访问用户telnet
,curl
,wget
等(可以访问明文http://169.254.169.254/1.0/user-data
)
您很容易受到代理请求攻击(例如,攻击者要求Apache可能会或可能不会在AMI上运行以获取和转发明文http://169.254.169.254/1.0/user-data
)
存储在AMI中并使用易于获得的密钥加密(或解密)数据的安全性user-data
低
易于获取的密钥(密码)可能包括:
密钥在ABI内部的脚本中进行硬编码(攻击者可以获取ABI)
密钥在AMI本身的脚本中进行硬编码,其中脚本可由任何设法登录AMI的用户读取
任何其他容易获得的信息,如公钥等.
任何私钥(其公钥可能很容易获得)
给定一个易于获得的密钥(密码),第1点中确定的相同问题适用,即:
解密的数据是可访问的任何谁管理,以登录到AMI和访问用户telnet
,curl
,wget
等(可以访问明文http://169.254.169.254/1.0/user-data
)
您很容易受到代理请求攻击(例如,攻击者要求Apache可能会或可能不会在AMI上运行以获取和转发加密的http://169.254.169.254/1.0/user-data
,使用易于获取的密钥进行解密)
存储在AMI中并使用不易获得的密钥加密时的数据安全性user-data
平均
加密后的数据是可访问的任何谁管理,以登录到AMI和访问用户telnet
,curl
,wget
等(可以访问加密http://169.254.169.254/1.0/user-data
)
然后可以使用暴力攻击来尝试解密加密数据
存储在AMI上的数据安全性,位于安全位置(没有加密值)
更高
数据只能由一个用户访问,用户需要数据才能运行
例如,用户拥有的文件:具有掩码0600或0400的用户
攻击者必须能够冒充特定用户才能获得对数据的访问权限
其他安全层,例如拒绝用户直接登录(必须通过root
以进行交互式模拟)可以提高安全性
因此,涉及AMI的任何方法user-data
都不是最安全的,因为获得对机器上任何用户的访问(最薄弱点)会危及数据.
如果仅在有限的时间段内(即仅在部署过程中)需要S3凭证,如果 AWS允许您覆盖或删除user-data
完成时的内容(但这似乎并非如此),则可以减轻这种情况case.)另一种选择是在部署过程期间创建临时S3凭证(如果可能)(user-data
在部署过程完成并且凭据已经使AWS无效后,不再构成安全性,从而损害这些凭据)威胁.)
如果以上不适用(例如,无限期地部署节点需要S3凭证)或不可能(例如,不能仅为部署发布临时S3凭证)那么最好的方法仍然是将子弹和scp
凭证咬到各个节点,可能并行,拥有正确的所有权和权限.
我写了一篇文章,研究了安全地将秘密传递给EC2实例的各种方法以及每种方法的优点和缺点.
http://www.shlomoswidler.com/2009/08/how-to-keep-your-aws-credentials-on-ec2.html
最好的方法是使用实例配置文件.基本思路是:
创建实例配置文件
创建一个新的IAM角色
将策略分配给先前创建的角色,例如:
{"声明":[{"Sid":"Stmt1369049349504","行动":"sqs:","效果":"允许","资源":" "}}}
将角色和实例配置文件关联在一起.
启动新的EC2实例时,请确保提供实例配置文件名称.
如果一切正常,并且您用于从EC2实例中连接到AWS服务的库支持从实例元数据中检索凭证,则您的代码将能够使用AWS服务.
从boto-user邮件列表中获取的完整示例:
首先,您必须创建一个JSON策略文档,该文档表示IAM角色应该有权访问的服务和资源.例如,此策略为存储桶"my_bucket"授予所有S3操作.您可以使用适合您的应用程序的任何策略.
BUCKET_POLICY = """{ "Statement":[{ "Effect":"Allow", "Action":["s3:*"], "Resource":["arn:aws:s3:::my_bucket"]}]}"""
接下来,您需要在IAM中创建实例配置文件.
import boto c = boto.connect_iam() instance_profile = c.create_instance_profile('myinstanceprofile')
获得实例配置文件后,您需要创建角色,将角色添加到实例配置文件并将策略与角色相关联.
role = c.create_role('myrole') c.add_role_to_instance_profile('myinstanceprofile', 'myrole') c.put_role_policy('myrole', 'mypolicy', BUCKET_POLICY)
现在,您可以在启动实例时使用该实例配置文件:
ec2 = boto.connect_ec2() ec2.run_instances('ami-xxxxxxx', ..., instance_profile_name='myinstanceprofile')
我想指出,不再需要为EC2实例提供任何凭据.使用IAM,您可以为EC2实例创建角色.在这些角色中,您可以设置细粒度策略,以允许您的EC2实例从特定S3存储桶中获取特定对象,而不是更多.您可以在AWS文档中阅读有关IAM角色的更多信息:
http://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html