AWS CloudFormation 将 EC2 实例 SSH 密钥提供给其他服务器

AWS CloudFormation 将 EC2 实例 SSH 密钥提供给其他服务器

我正在使用 CloudFormation 创建 EC2 实例。我要做的第一件事是签出包含 puppet 清单的 git 存储库。为此,我需要一个 SSH 密钥。

将密钥发送到服务器的最佳方法是什么?这是我考虑过的:

  • 使用 KMS,但这似乎不允许您“存储密钥以供日后使用”
  • 使用 EC2 密钥对,但这似乎也不允许您稍后获取私钥
  • 将密钥写入UserData属性,但(尽管它的名字如此)这似乎不适合存储任何类型的数据,更不用说敏感数据了
  • 将其存储在 S3 存储桶中,但我不确定如何设置存储桶上的权限以允许 EC2 实例使用 aws cli 工具提取数据

这似乎是一件很常见的事情,但是我一定是在寻找错误的东西,因为我找不到合理的答案。

答案1

处理此问题的直接方法是将您的机密(如 SSH 密钥)存储在专用的 S3 存储桶中,然后授予 EC2 实例对该存储桶的访问权限。

您可以先创建一个 IAM 角色:

"DeploymentRole" : {
  "Type" : "AWS::IAM::Role",
  "Properties" : {
    "Policies" : [{
      "PolicyName" : "SecretsBucketPolicy",
      "PolicyDocument" : {
        "Version" : "2012-10-17",
        "Statement" : [{
          "Resource" : "arn:aws:s3:::wherever-the-secrets-are-stored/*",
          "Action" : ["s3:GetObject"],
          "Effect" : "Allow"
        }]
      }
    }],
    "Path" : "/",
    "AssumeRolePolicyDocument" : {
      "Version" : "2012-10-17",
      "Statement" : [{
        "Action" : ["sts:AssumeRole"],
        "Principal" : {"Service": ["ec2.amazonaws.com"]},
        "Effect" : "Allow"
      }]
    }
  }
}

该角色定义了一个策略,允许其读取秘密存储桶,并允许 EC2 承担该角色。

然后为该角色创建一个实例配置文件:

"DeploymentProfile" : {
  "Type" : "AWS::IAM::InstanceProfile",
  "Properties" : {
    "Roles" : [{"Ref" : "DeploymentRole"}],
    "Path" : "/"
  }
}

对于您的 EC2 实例或启动配置,您现在可以使用该IamInstanceProfile属性将此配置文件分配给实例。

然后秘密存储桶就应该是可读的了。

答案2

如果您需要 OpsWorks 菜谱存储库或应用程序部署的 SSH 密钥,则 S3 存储桶方法不起作用。

另一个解决方案是,您可以添加一个 SSH 密钥类型的参数CommaDelimitedList,其中换行符用逗号替换,然后Fn::Join在需要的地方将密钥的行重新组合在一起。

CloudFormation 模板示例:

{
  "Parameters": {
    "CookbooksDeployKey": {
      "Type": "CommaDelimitedList",
      "Description": "Enter the deploy key as CSV (replace newlines with commas)",
      "NoEcho": true
    }
  },
  "Resources": {
    "myStack": {
      "Type": "AWS::OpsWorks::Stack",
      "Properties": {
        "CustomCookbooksSource": {
          "Type": "git",
          "Url": "[email protected]:user/repository.git",
          "Revision": "master",
          "SshKey": {"Fn::Join": ["\n", {"Ref": "CookbooksDeployKey"}]}
        }
      }
    }
  }
}

要生成私钥文件的单行“CSV”格式版本,可以使用以下 sed 命令(这只是用逗号替换文件中的所有换行符,并在标准输出上返回结果):

sed ':a;N;$!ba;s/\n/,/g' /home/user/.ssh/id_rsa

结果如下所示:

-----BEGIN RSA PRIVATE KEY-----,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,-----END RSA PRIVATE KEY-----

然后,您可以在 CloudFormation 中创建或更新堆栈时将该值粘贴到参数中。

相关内容