我在AWS上有2个账户。在第一个帐户上,我创建了一个具有"dbSG"安全组的永久EC2实例(仅允许通过特定端口和IP进行连接)。
当我使用CloudFormation模板在第二个帐户中创建实例时,它应该:
- 将此实例IP添加到"dbSG"安全组,并允许通过特定端口连接。 通过此端口连接到第一个实例。
当在第二个帐户中创建实例并修改"dbSG"以允许来自该实例的连接时,我可以在UserData中使用assumption role吗?如果是,如何逐步完成?
For EC2-Classic
ec2 authorize-security-group-ingress
的CLI帮助有如下示例:
添加允许来自安全的入站HTTP流量的规则组在其他帐户
本例启用来自某个源的TCP端口80的入方向流量另一个AWS中的安全组(otheraccountgroup)账户(123456789012)。如果命令执行成功,则无输出返回。
命令:
aws ec2 authorization -security-group-ingress——group-name我的安全组——协议tcp——端口80——源组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
Via CloudFormation: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-sourcesecuritygroupownerid
不幸的是,这似乎不适用于VPC中的实例,而只适用于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"实例上,你可以添加以下User-data脚本(通过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 Role必须允许调用sts:AssumeRole
。
警告:如果你停止并重新启动实例,它的公共IP将会改变(除非你已经分配了一个ElasticIP)。因为用户数据脚本只在第一次启动时执行,所以dbSG不会得到更新。
通过λ
你也可以使用由CloudTrail或Config触发的Lambda函数,尽管这有点棘手:在创建新的AWS EC2实例时运行AWS Lambda代码
这样,您还可以跟踪对StopInstance和StartInstance的调用,并以更健壮的方式更新(撤销/授权)dbSG规则。
引用:
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html
- https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html主要
看来你的情况是:
- 两个vpc,我们叫它们:VPC-A和VPC-B
- 每个VPC由不同的AWS帐户拥有
- 实例a在VPC-A中存在,安全组
dbSG
- 在VPC-B中启动Instance-B时,允许其访问Instance-A
实现这一点的最简单方法是通过VPC对等连接,它允许同一区域内的两个VPC之间直接通信。vpc可以属于不同的AWS帐户,但IP地址范围不能重叠。
过程如下:
- VPC-A邀请VPC-B对端
- VPC-B接受邀请
- 在两个vpc中更新路由表以相互发送流量
- 在VPC-B中新建安全组,如
appSG
- 修改
dbSG
允许来自appSG
的传入连接 - 将Instance-B(以及任何其他应该与Instance-A通信的实例)与
appSG
安全组 关联
就是这样!安全原理与VPC内部相同。唯一的区别是实例位于单独的vpc中,这些vpc已经对等在一起。
参见:使用VPC对等连接