从另一个AWS账户编辑EC2安全组

时间:2016-10-31 19:30:26

标签: amazon-ec2 amazon-cloudformation aws-security-group

我在AWS上有2个帐户。在第一个帐户中,我创建了一个带有“dbSG”安全组的永久EC2实例(仅允许通过特定端口和IP进行连接)。

当我使用CloudFormation模板在第二个帐户中创建实例时,它应该:

  • 将此实例IP添加到“dbSG”安全组,并允许通过特定端口进行连接。
  • 通过此端口连接到第一个实例。

我可以在第二个帐户中创建实例时在UserData中使用AssumeRole并修改“dbSG”以允许来自此实例的连接吗?如果是的话,如何逐步完成?

2 个答案:

答案 0 :(得分:3)

对于EC2-Classic

ec2 authorize-security-group-ingress的CLI帮助有这个例子:

  

添加允许来自安全性的入站HTTP流量的规则   另一个帐户中的小组

     

此示例启用来自源的TCP端口80上的入站流量   不同AWS中的安全组(otheraccountgroup)   帐户(123456789012)。如果命令成功,则没有输出   返回。

     

命令:

     

aws ec2 authorize-security-group-ingress --group-name   MySecurityGroup --protocol tcp --port 80 --source- group   otheraccountgroup --group-owner 123456789012

因此,只要您知道“appSG”的安全组ID,并使用“db”帐户的凭据:

aws ec2 authorize-security-group-ingress --group-name
dbSG --protocol tcp --port 1234 --source-group
appSG --group-owner XXX-APP-ACCOUNT-ID

通过CloudFormation:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-sourcesecuritygroupownerid

不幸的是,这似乎不适用于VPC中的Instances,而只适用于EC2-Classic。

对于EC2-VPC:user-data方式

在“db”帐户中,向CF模板添加一个角色,指定一个信任策略,允许此角色由另一个AWS账户中的特定角色承担:

(将XXX -...替换为您自己的值)

'RoleForOtherAccount': {
  'Type': 'AWS::IAM::Role',
  'Properties': {
    'AssumeRolePolicyDocument': {
      'Version': '2012-10-17',
      'Statement': [{
        'Effect': 'Allow',
        'Principal': {
          'AWS': "arn:aws:iam::XXX-OTHER-AWS-ACCOUNT-ID:role/XXX-ROLE-NAME-GIVEN-TO-APP-INSTANCES"
        },
        'Action': ['sts:AssumeRole']
      }]
    },
    'Path': '/',
    'Policies': [{
      'PolicyName': 'manage-sg',
      'PolicyDocument': {
        'Version': '2012-10-17',
        'Statement': [
          {
            'Effect': 'Allow',
            'Action': [
              'ec2: AuthorizeSecurityGroupIngress'
            ],
            'Resource': '*'
          }
        ]
      }
    }]
  }
}

然后,在“app”实例上,您可以添加以下用户数据脚本(通过CloudFormation: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-userdata

#!/bin/bash

# get current public IP address via EC2 meta-data
MY_IP=$(wget -qO- http://instance-data/latest/meta-data/public-ipv4)

# assume the "db" account role and get the credentials
CREDENTIALS_JSON=$(aws sts assume-role --role-arn XXX-ARN-OF-ROLE-IN-DB-ACCOUNT --role-session-name "AppSessionForSGIngress" --query '{"AWS_ACCESS_KEY_ID": Credentials.AccessKeyId, "AWS_SECRET_ACCESS_KEY": Credentials.SecretAccessKey, "AWS_SESSION_TOKEN": Credentials.SessionToken }')

# here you should find a way to extract AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN from the above $CREDENTIALS_JSON, then export them or pass as values replacing YYY below

# authorize the IP
aws --region XXX-DB-REGION --access-key-id YYY --secret-access-key YYY --session-token YYY ec2 authorize-security-group-ingress --group-id sg-XXX --protocol tcp --port 1234 --cidr $MY_IP/32

“app”实例的IAM角色必须允许调用sts:AssumeRole

警告:如果您停止并重新启动实例,其公共IP将会更改(除非您已分配ElasticIP)。由于用户数据脚本仅在第一次启动期间执行,因此您的dbSG不会更新。

via Lambda

你也可以使用由CloudTrail或Config触发的Lambda函数,尽管这有点棘手:Run AWS Lambda code when creating a new AWS EC2 instance

这样,您还可以跟踪对StopInstance和StartInstance的调用,并以更强大的方式更新(撤消/授权)dbSG规则。

参考文献:

答案 1 :(得分:2)

您的情况似乎是:

  • 两个VPC,我们称之为:VPC-A和VPC-B
  • 每个VPC由不同的AWS账户拥有
  • 实例-A存在于VPC-A中,具有Securiy Group dbSG
  • 在VPC-B中启动Instance-B时,允许它访问Instance-A

实现此目的的最简单方法是通过VPC Peering,它允许同一区域内两个VPC之间的直接通信。 VPC可以属于不同的AWS账户,但必须具有不重叠的IP地址范围。

过程将是:

  • VPC-A邀请VPC-B加入对等
  • VPC-B接受邀请
  • 两个VPC中的
  • Update routing tables将流量发送给对方
  • 在VPC-B中创建一个安全组,例如appSG
  • 修改dbSG以允许来自appSG
  • 的传入连接
  • 将实例-B(以及应与实例-A通信的任何其他实例)与appSG安全组相关联

就是这样!安全在对等VPC之间以与VPC内相同的方式工作。唯一的区别是实例位于已经对等的单独VPC中。

请参阅:Working with VPC Peering Connections