我怎么能(安全)下载一个私人S3资产与上一cloudinit新的EC2实例?(How can I (

2019-06-26 02:36发布

我使用CloudFormation来管理一个Tomcat Web服务器堆栈,但我厌倦了原AMI管理新的应用程序版本。 我想在厨师的方向移动,但没有时间,现在。 相反,我打天下的Web服务器实例化一个简单的问题:我如何可以下载一个“电流” WAR当新机起旋?

我的想法是利用私人S3桶和cloudinit,但我有点被如何处理IAM凭证做难住了。 我可以把他们的模板的用户数据,但我讨厌这样做,特别是因为我的版本控制该文件。 我能想到的唯一的选择是在AMI本身使用环境变量。 他们必须是明文,但是......呃,如果你能闯进我的情况下,你可以拉上和下载我的整个网络服务器。 只要IAM用户没有重用为别的,并定期轮换,这似乎是解决问题的合理方法。 我错过了什么? 我怎样才能安全地使用cloudinit下载一个私人S3资产?

Answer 1:

亚马逊最近宣布了一项新的功能,您可以给“IAM角色”到你的EC2实例。 这使得它很容易让特定情况下有读权限的具体S3资源。

这里是他们的博客中宣布新的特点:

http://aws.typepad.com/aws/2012/06/iam-roles-for-ec2-instances-simplified-secure-access-to-aws-service-apis-from-ec2.html

这里的EC2文档中的部分:

http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/UsingIAM.html#UsingIAMrolesWithAmazonEC2Instances

这里的IAM文档中的部分:

http://docs.amazonwebservices.com/IAM/latest/UserGuide/WorkingWithRoles.html

IAM角色使凭据可通过HTTP的实例,因此在实例上运行的任何用户或进程可以看到它们。



Answer 2:

要更新这个问题的答案了一下:

随着IAM角色,新的AWS命令行客户端 ,使获取这些资产微不足道。 它会自动通过拉IAM从环境赋予AWS凭证和处理这些凭证的刷新。

下面是在用户数据脚本安全S3桶取出一个单一资产的例子:

# Install the AWS command-line tools
pip install awscli

# Fetch the asset
aws s3 cp --region us-east-1 s3://my-private-bucket/a-folder/an-asset.zip /some/destination

就那么简单。 您也可以整个目录内容从S3复制和上传等请参见参考资料以获取更多详细信息和选项。



Answer 3:

与IAM角色的实例有自动旋转的临时安全证书。 他们是通过HTTP提供http://169.254.169.254/latest/meta-data/iam/security-credentials/RoleName ,其中角色名是不管你叫你的角色。 所以他们很容易从你的情况下得到的,但他们定期失效。

使用起来有点困难。 CloudFormation不能直接使用的临时凭证。 亚马逊的Linux AMI有Python的博托安装,并且它现在足够聪明,发现并自动使用这些证书给你。 这里有一个一行,你可以把一个脚本来从S3桶B,k到本地文件F文件:

python -c "import boto;boto.connect_s3().get_bucket('b').get_key('k').get_contents_to_filename('f')"

伯特找到并使用该角色的临时凭证给你,这使得它很容易使用。



Answer 4:

为了安全地下载一个私人S3资产到一个新的EC2实例,你应该使用IAM角色的EC2给予必要的S3允许您的EC2实例,然后调用aws s3 cp在您的实例的的UserData cloudinit脚本下载资产。

要设置从CloudFormation模板EC2的IAM角色,使用AWS::IAM::InstanceProfile资源,引用一个AWS::IAM::Role资源与AssumeRolePolicyDocument委派访问ec2.amazonaws.com ,与设计成政策授予最低权限 (在这种情况下,允许's3:GetObject'只为正在下载的特定资产S3)。

下面是使用cloudinit,返回其内容的下载的S3资产到一个新的EC2实例一个完整的示例模板堆输出 :

Description: (securely) download a private S3 asset onto a new EC2 instance with cloudinit
Parameters:
  S3Bucket:
    Description: S3 bucket name
    Type: String
  S3Key:
    Description: S3 object key
    Type: String
Mappings:
  # amzn-ami-hvm-2016.09.1.20161221-x86_64-gp2
  RegionMap:
    us-east-1:
      "64": "ami-9be6f38c"
Resources:
  EC2Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
          Principal: {Service: [ ec2.amazonaws.com ]}
          Action: ["sts:AssumeRole"]
      Path: /
      Policies:
      - PolicyName: EC2Policy
        PolicyDocument:
          Version: 2012-10-17
          Statement:
          - Effect: Allow
            Action: ['s3:GetObject']
            Resource: !Sub 'arn:aws:s3:::${S3Bucket}/${S3Key}'
  RootInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles: [ !Ref EC2Role ]
  WebServer:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", 64 ]
      InstanceType: m3.medium
      IamInstanceProfile: !Ref RootInstanceProfile
      UserData:
        "Fn::Base64":
          !Sub |
            #!/bin/bash
            DATA=$(aws s3 cp s3://${S3Bucket}/${S3Key} -)
            /opt/aws/bin/cfn-signal \
              -e $? \
              -d "$DATA" \
              '${Handle}'
  Handle:
    Type: AWS::CloudFormation::WaitConditionHandle
  Wait:
    Type: AWS::CloudFormation::WaitCondition
    Properties:
      Handle: !Ref Handle
      Timeout: 300
Outputs:
  Result:
    Value: !GetAtt Wait.Data


文章来源: How can I (securely) download a private S3 asset onto a new EC2 instance with cloudinit?