Назад | Перейти на главную страницу

Можно ли скопировать группу безопасности AWS?

У нас есть группы безопасности, в которых довольно много правил. Вместо того, чтобы воссоздавать одни и те же правила для ряда групп безопасности, чтобы учесть незначительные различия, можно ли скопировать группу безопасности для использования в качестве отправной точки или использовать наследование и т. Д.?

Не похоже, что вы можете копировать группы безопасности из веб-интерфейса. Однако вы можете использовать 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 позволяет вам выбрать группу безопасности и выполнить операцию «Копировать в новую» в пользовательском интерфейсе.

Из AWS Создание группы безопасности docs, вы можете скопировать группу безопасности с помощью консоли.

  1. Выберите группу безопасности, которую хотите скопировать
  2. Выбрать действие
  3. Копировать в новый

Вот метод 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 

Рассмотрите возможность взглянуть на этот блог. Это может быть полезно для того, на что вы смотрите.

http://ry4an.org/unblog/post/ec2_security_group_tools/

Вот сценарий, который я сделал для этого: aws_sg_migrate

Пример использования

python3 aws_sg_migrate.py --vpc=vpc-05643b6c --shell --src=us-east-1 --dest=us-west-1 sg-111111

Это основано на этом и адаптирован для Python3.

В том же регионе AWS вы можете скопировать политику безопасности с помощью онлайн-графического интерфейса. Однако иногда вы хотите скопировать что-то программным способом. Например, если у вас есть много политик безопасности, которые нужно скопировать, или если вы хотите скопировать по регионам.

Вот простой фрагмент, чтобы сделать это.

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'])

Из-за отсутствия правильного способа сделать это в Интернете, я создал очень простой скрипт для этого. Посмотрите, если вам интересно.

https://github.com/pedropregueiro/migrate-ec2-secgroups

В консоли EC2 нажмите Launch Instance и продолжайте вводить фиктивную информацию, пока не дойдете до раздела группы безопасности.

Отсюда нажмите «Выбрать существующую группу безопасности», и ниже вы увидите все группы безопасности, которые у вас есть для этого конкретного VPC. Вы должны увидеть ссылку «Copy to New» в разделе «Actions», используйте ее, чтобы скопировать все ваши ACL в новую SG.

Или я полагаю, вы могли бы использовать скрипт - это быстрее IMO ..

У меня была аналогичная проблема, но с копированием 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)