将AWS凭证作为用户数据传递给EC2实例的最佳方法是什么?

时间:2009-03-12 23:05:47

标签: encryption amazon-s3 amazon-ec2 amazon-web-services

我有一个基于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脚本中。虽然它确实有效,但我的方法有两个问题。

  1. 'zip -P'不是很安全
  2. 密码在实例中是硬编码的(它始终是'秘密密码')
  3. 该方法与描述here

    的方法非常相似

    是否有更优雅或更接受的方法?使用gpg加密凭证并在实例上存储私钥来解密它是我现在正在考虑的一种方法,但我不知道任何警告。我可以直接使用AWS密钥对吗?我错过了一些非常明显的API部分吗?

5 个答案:

答案 0 :(得分:12)

您可以将凭据存储在计算机上(或转移,使用,然后将其删除。)

您可以通过安全通道传输凭据(例如,使用scp进行非交互式身份验证,例如密钥对),这样您就不需要执行任何自定义加密(仅确保将权限正确设置为密钥文件始终0400,例如设置主文件的权限并使用scp -p

如果上述内容未能解答您的问题,请提供更具体的详细信息。您的设置是什么以及您想要实现的目标。 EC2操作是从中心位置在多个节点上启动的吗? SSH节点和中心位置之间是否可用?等


修改

您是否考虑过parameterizing your AMI,要求实例化您的AMI的人首先使用他们的AWS密钥填充用户数据(ec2-run-instances -f user-data-file)?然后,您的AMI可以从http://169.254.169.254/1.0/user-data动态检索这些每个实例的参数。


<强>更新

好的,这是对目前讨论的各种方法的安全性比较:

  1. 存储在AMI user-data未加密时的数据安全性
    • 任何用户都可以访问明文数据,该用户可以登录AMI并有权访问telnetcurlwget等。 (可以访问明文http://169.254.169.254/1.0/user-data
    • 您容易受到代理请求攻击(例如,攻击者要求Apache可能会或可能不会在AMI上运行以获取和转发明文http://169.254.169.254/1.0/user-data
  2. 存储在AMI user-data中并使用易于获取的密钥加密(或解密)时的数据安全性
    • 易于获取的密钥(密码)可能包括:
      • 在ABI内部的脚本中进行硬编码(攻击者可以获取ABI)
      • 在AMI本身的脚本中进行硬编码的密钥,其中脚本可供任何用户登录AMI的用户阅读
      • 任何其他易于获取的信息,如公钥等。
      • 任何私钥(其公钥可能很容易获得)
    • 给出一个易于获得的密钥(密码),第1点中指出的相同问题适用,即:
      • 任何用户都可以访问解密数据,该用户可以登录AMI并有权访问telnetcurlwget等。(可以访问明文http://169.254.169.254/1.0/user-data
      • 您很容易受到代理请求攻击(例如,攻击者要求Apache可能会或可能不会在AMI上运行以获取和转发加密的http://169.254.169.254/1.0/user-data,并使用易于获取的密钥进行解密;
  3. 存储在AMI user-data中并使用不易获取的密钥加密时的数据安全性
    • 平均
    • 任何用户都可以访问加密数据,该用户可以登录AMI并有权访问telnetcurlwget等。(可以访问加密的http://169.254.169.254/1.0/user-data
      • 然后可以使用暴力攻击来尝试解密加密数据
  4. 存储在AMI上,安全位置时的数据安全性(无加密值)
    • 更高
    • 数据只能由一个用户访问,用户需要数据才能运行
      • e.g。用户拥有的文件:掩码为0600或0400的用户
    • 攻击者必须能够冒充特定用户才能获得对数据的访问权限
      • 其他安全层,例如拒绝用户直接登录(必须通过root进行交互式模拟)可提高安全性
  5. 因此,涉及AMI user-data的任何方法都不是最安全的,因为获取对机器上任何用户的访问权限(最弱点)会危及数据。

    如果仅在有限的时间内(即仅在部署过程中)需要S3凭证,则可以减轻这种情况,如果 AWS允许您覆盖或删除{{1完成后(但似乎并非如此。)另一种方法是在部署过程中创建临时S3凭证,如果可能的话(从user-data中妥协这些凭据,部署过程完成后,凭据已使AWS无效,不再构成安全威胁。)

    如果以上内容不适用(例如,无限期地部署节点需要S3凭证)或不可能(例如,无法仅为部署发布临时S3凭证),那么最好的方法仍然是咬住子弹并user-data凭据具有正确的所有权和权限的各个节点,可能是并行的。

答案 1 :(得分:11)

我写了一篇文章,研究了安全地将秘密传递给EC2实例的各种方法以及专业知识。每个人的利弊。

http://www.shlomoswidler.com/2009/08/how-to-keep-your-aws-credentials-on-ec2.html

答案 2 :(得分:10)

最好的方法是使用instance profiles。基本思路是:

  • 创建实例个人资料
  • 创建新的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')

答案 3 :(得分:7)

我想指出,不再需要为EC2实例提供任何凭据。使用IAM,您可以为EC2实例创建角色。在这些角色中,您可以设置细粒度策略,以允许您的EC2实例从特定S3存储桶中获取特定对象,而不是更多。您可以在AWS文档中阅读有关IAM角色的更多信息:

http://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html

答案 4 :(得分:1)

与其他人已在此处指出的一样,您不需要通过使用IAM角色来存储EC2实例的AWS凭证 -  https://aws.amazon.com/blogs/security/a-safer-way-to-distribute-aws-credentials-to-ec2/。 我将补充说,您也可以使用相同的方法为您的EC2实例安全存储非AWS凭证,例如,如果您有一些要保证安全的数据库凭据。您可以在S3 Bukcet上保存非aws凭据,并使用IAM角色访问该存储桶。 你可以在这里找到更详细的信息 - https://aws.amazon.com/blogs/security/using-iam-roles-to-distribute-non-aws-credentials-to-your-ec2-instances/