特定IPからのアクセスを許可するセキュリティグループを取得する(Python)


はじめに

こんにちは、クラスメソッド サービスグロースチームの筧です。

今回は特定IPからのアクセスを許可するセキュリティグループの存在確認方法について、ブログ向けに汎化してご紹介します。

コード

https://github.com/takaakikakei/sls-services-snippet/commit/1edc76385364da0b80f09941b0ea213568b3a4f4

説明

クラス

引数に実行先のboto3セッションを指定して、インスタンスを作成するクラスです。

ec2.py
class EC2Service:
    def __init__(self, session: boto3.Session):
        self._session = session
        self._ec2: EC2Client = session.client("ec2")

有効化されているリージョン取得するメソッド

describe_regionsメソッドで、実行先アカウントで有効化されているリージョンを取得します。

ec2.py
    def describe_regions(self) -> List:
        """
        refs:
        https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_regions
        """
        try:
            regions = list(
                map(lambda x: x["RegionName"], self._ec2.describe_regions()["Regions"])
            )
            return regions
        except Exception as e:
            logger.error(e)
            return []

参考

https://dev.classmethod.jp/articles/iterate-all-region-with-python-boto3/

特定IPからのアクセスを許可するセキュリティグループを取得するメソッド

describe_target_security_groupsメソッドで、取得したいセキュリティグループを取得します。有効化されているリージョンをリスト形式で引数に指定します。

ec2.py
    def describe_target_security_groups(self, regions) -> Dict:
        """
        refs:
        https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Paginator.DescribeSecurityGroups
        """

今回のコードでは、特定IPアドレスを許可するセキュリティグループを取得するようなコードになっています。TARGET_SG_IPに対象IPをリスト形式で指定します。

ec2.py
        # 取得したいセキュリティグループのipadressを配列形式で指定
        # TARGET_SG_IP = [xx.xx.xx.xx, yy.yy.yy.yy]
        TARGET_SG_IP = []

またPaginatorを利用して複数ページにまたがる場合に対応しています。

ec2.py
        target_sg_all_regions = {}

        for region_name in regions:
            try:
                target_sg = []

                ec2 = self._session.client("ec2", region_name=region_name)
                paginator = ec2.get_paginator("describe_security_groups")
                response_iterator = paginator.paginate(
                    Filters=[
                        {
                            "Name": "ip-permission.cidr",
                            "Values": TARGET_SG_IP,
                        }
                    ]
                )
                for page in response_iterator:
                    if page["SecurityGroups"] == []:
                        continue
                    for security_group in page["SecurityGroups"]:
                        target_sg.append(security_group["GroupName"])

                if target_sg == []:
                    continue
                target_sg_all_regions[region_name] = copy.deepcopy(target_sg)
            except Exception as e:
                logger.error(e)
                return {}

        return target_sg_all_regions

あとがき

最後まで読んでいただきありがとうございます。
他サービスについても、今後スニペットを紹介予定なのでお楽しみに。

それではまた!