我们有一些安全组,其中包含很多规则。不必为了适应微小差异而为多个安全组重新创建相同的规则,是否可以复制安全组用作起点或使用继承等?
我们有一些安全组,其中包含很多规则。不必为了适应微小差异而为多个安全组重新创建相同的规则,是否可以复制安全组用作起点或使用继承等?
Answers:
您似乎无法从Web界面复制安全组。但是,您可以使用AWS CLI来创建安全组:
命令:
$ aws ec2 describe-security-groups --group-id MySecurityGroupID
输出:
{
"securityGroupInfo": [
{
"ipPermissionsEgress": [],
"groupId": "sg-903004f8",
"ipPermissions": [],
"groupName": "MySecurityGroup",
"ownerId": "803981987763",
"groupDescription": "AWS-CLI-Example"
}
],
"requestId": "afb680df-d7b1-4f6a-b1a7-344fdb1e3532"
}
并使用命令添加规则:
aws ec2 authorize-security-group-ingress --group-id MySecurityGroupID --ip-protocol tcp --from-port 22 --to-port 22 --cidr-ip 0.0.0.0/0
输出:
{
"return": "true",
"requestId": "c24a1c93-150b-4a0a-b56b-b149c0e660d2"
}
从那里您应该能够弄清楚如何简化安全组的创建。
aws ec2 describe-security-groups --group-id MySecurityGroupID --region us-west-2
考虑看看这个博客。它可能对您正在查看的内容很有用。
Use of uninitialized value $type in string eq at create-firewall-script.pl line 43, <> line 1 (#1)
这是我编写的自定义库中的“复制安全组” python / boto方法,它使这些事情变得更容易/使它们自动化。.最终,这是我想出的解决方案。
vpcId is the Virtual Private Cloud Id
keys is a dictionary with your AWS keys
其余的应该直接弄清楚。
def copyEC2SecurityGroup(self, keys, region, securityGroupName, newSecurityGroupName = None, newRegion = None, vpcId = None):
newEc2Connection = None
print("Creating ec2Connection for source region: " + region)
ec2Connection = lib.getEc2Connection(region, keys)
if newRegion is None:
newRegion = region
else:
print("New Region Detected, creating for New region: " + newRegion)
newEc2Connection = lib.getEc2Connection(newRegion, keys)
newRegionInfo = newEc2Connection.region
print("new region is: %s" % newRegion)
if newSecurityGroupName is None:
newSecurityGroupName = securityGroupName
print ("new security group is: %s" % newSecurityGroupName)
# if copying in the same region the new security group cannot have the same name.
if newRegion == region:
if newSecurityGroupName == securityGroupName:
print ("Old and new security groups cannot have the same name when copying to the same region.")
exit(1)
groups = [group for group in ec2Connection.get_all_security_groups() if group.name == securityGroupName]
print"got groups count " + str(len(groups))
if groups:
theOldGroup = groups[0]
print theOldGroup.rules
else:
print("Can't find security group by the name of: %s" % securityGroupName)
exit(1)
print groups
pprint(theOldGroup)
if newEc2Connection is not None:
print("Creating new security group in new region")
sg = newEc2Connection.create_security_group(newSecurityGroupName, newSecurityGroupName, vpcId)
sleep(5)
else:
print("Creating new security group in current region")
sg = ec2Connection.create_security_group(newSecurityGroupName, newSecurityGroupName, vpcId)
sleep(5)
source_groups = []
for rule in theOldGroup.rules:
for grant in rule.grants:
strGrant = str(grant)
print(strGrant)
if strGrant.startswith("sg"):
print("Cannot copy 'security group rule' (%s)... only cidr_ip's e.g. xxx.xxx.xxx.xxx/yy." % strGrant)
continue
grant_nom = grant.name or grant.group_id
if grant_nom:
if grant_nom not in source_groups:
source_groups.append(grant_nom)
sg.authorize(rule.ip_protocol, rule.from_port, rule.to_port, grant)
else:
sg.authorize(rule.ip_protocol, rule.from_port, rule.to_port, grant.cidr_ip)
return sg
这是我完成此任务的脚本:aws_sg_migrate
样本用法为
python3 aws_sg_migrate.py --vpc=vpc-05643b6c --shell --src=us-east-1 --dest=us-west-1 sg-111111
它基于此,并且适用于Python3。
在同一AWS区域内,您可以使用在线GUI复制安全策略。但是,有时您希望以编程方式复制内容。例如,如果要复制很多安全策略,或者要跨区域复制。
这是一个简单的代码片段。
import boto3
from os import environ as env
def copy_security_groups(src_region, tgt_region, grp_names):
# Initialize client connections for regions
src_client = boto3.client('ec2', region_name=src_region,
aws_access_key_id=env['AWS_ACCESS_KEY_ID'],
aws_secret_access_key=env['AWS_SECRET_ACCESS_KEY'])
tgt_client = boto3.client('ec2', region_name=tgt_region,
aws_access_key_id=env['AWS_ACCESS_KEY_ID'],
aws_secret_access_key=env['AWS_SECRET_ACCESS_KEY'])
# Get info for all security groups and copy them one-by-one
g_info = src_client.describe_security_groups(
GroupNames=grp_names)['SecurityGroups']
for g in g_info:
resp = tgt_client.create_security_group(
GroupName=g['GroupName'], Description=g['Description'])
new_grp_id = resp['GroupId']
tgt_client.authorize_security_group_ingress(
GroupId=new_grp_id, IpPermissions=g['IpPermissions'])
tgt_client.authorize_security_group_egress(
GroupId=new_grp_id, IpPermissions=g['IpPermissionsEgress'])
if __name__ == '__main__':
copy_security_groups('us-east-1', 'ap-south-1', ['rds-public'])
我有一个类似的问题,但在不同帐户之间复制了SG。
只需在开头指定一些常量,函数copy_sg就会复制它们。
没有错误检查,因此如果目标SG已经存在,它将失败。
请遵循可以在帐户内使用的一般解决方案:
#!/usr/bin/env python3
# coding: utf-8
import boto3
from typing import Any, List
# This profile needs to be able to assume the specified role in SRC/TGT account
appops_session = boto3.Session(profile_name='YOUR_PRECONFIGURE_PROFILE')
ROLE = "THE ROLE TO BE ASSUMED" # I presume it is the same in SRC/TGT Account
SRC_ACCOUNT = "YOUR SRC ACCOUNT NUMBER"
TGT_REGION = "eu-central-1"
DST_ACCOUNT = "YOUR TARGET ACCOUNT NUMBER"
TGT_VPC = "vpc-XXXXXXXXXXXXXXX"
region = "ap-southeast-2"
dst_vpc_id = "vpc-XXXXXXXXXXXXXXX"
sg_list = ["sg-XXXXXXXX", "sg-YYYYYYYYY"]
def aws_sts_cred(account, role):
"""Get the STS credential.
return credential_object
"""
sts_creds = {}
sts_conn = appops_session.client('sts')
role_arn = "arn:aws:iam::" + account + ":role/" + role
assumed_role = sts_conn.assume_role(RoleArn=role_arn,
RoleSessionName="TMPROLE")
sts_creds["aws_access_key_id"] = assumed_role['Credentials']['AccessKeyId']
sts_creds["aws_secret_access_key"] = assumed_role['Credentials']['SecretAccessKey']
sts_creds["aws_session_token"] = assumed_role['Credentials']['SessionToken']
return sts_creds
def aws_conn(service: str, region: str, **kwargs) -> Any:
"""Create a client object."""
return boto3.client(service, region_name=region, **kwargs)
def dump_sg(client, vpcid: str = "", sgids: List = []) -> List:
"""Dump the specified SG."""
print(sgids)
sg_info = client.describe_security_groups(
Filters = [{'Name': 'group-id', 'Values': sgids}])['SecurityGroups']
return sg_info
def copy_sg(tgt_client, sgs, vpcid=""):
for sg in sgs:
# With no Vpc ID the SG is created in the default VPC.
resp = tgt_client.create_security_group(
GroupName=sg['GroupName'], Description=sg['Description'], VpcId=vpcid)
new_grp_id = resp['GroupId']
tgt_client.authorize_security_group_ingress(
GroupId=new_grp_id, IpPermissions=sg.get('IpPermissions', list()))
if sg.get('IpPermissionsEgress') != []:
# It doesn't work with an empty list
tgt_client.authorize_security_group_egress(
GroupId=new_grp_id, IpPermissions=sg.get('IpPermissionsEgress'))
print("Create SG {} - \"{}\" - \"{}\" in VPCID: {}".format(new_grp_id, sg['GroupName'], sg['Description'], vpcid))
STS_CRED = aws_sts_cred(SRC_ACCOUNT, ROLE)
STS_CRED_TGT = aws_sts_cred(DST_ACCOUNT, ROLE)
src_client = aws_conn("ec2", region, **STS_CRED)
sg_list = dump_sg(src_client, sgids=sg_list)
tgt_client = aws_conn("ec2", TGT_REGION, **STS_CRED_TGT)
copy_sg(tgt_client, sg_list)