> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Default security group unrestricted remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are step‑by‑step instructions to remove unrestricted inbound access from **default** Security Groups in AWS using the **AWS Management Console**.

        ***

        ## 1. Identify default Security Groups

        1. Sign in to the **AWS Management Console**.
        2. Go to **EC2**:
           * In the services search bar, type **EC2** and click **EC2**.
        3. In the left navigation pane, under **Network & Security**, click **Security Groups**.
        4. In the Security Groups list:
           * Add the column **Group Name** and **VPC ID** if not visible.
           * Default Security Groups typically have **Group Name** like `default` and **Description**: “default VPC security group”.
        5. You can also filter:
           * In the search bar, type: `group-name = default`\
             This will show one default Security Group per VPC.

        ***

        ## 2. Check for unrestricted inbound rules

        For each **default** Security Group:

        1. Select the Security Group.
        2. At the bottom, open the **Inbound rules** tab.
        3. Look for any rules that:
           * Have **Type** = `All traffic`, `All TCP`, `All UDP`, or specific ports like `SSH (22)`, `RDP (3389)`, `HTTP (80)`, `HTTPS (443)` etc.
           * And **Source** = `0.0.0.0/0` (IPv4) and/or `::/0` (IPv6).\
             These are “unrestricted inbound” rules.

        ***

        ## 3. Remove or restrict inbound rules on the default Security Group

        You cannot delete the default Security Group, but you can change its rules.

        1. With the default Security Group selected, click **Edit inbound rules**.
        2. For each rule that has **Source** `0.0.0.0/0` or `::/0`:
           * Either:
             * **Delete** the rule (click the trash icon), **or**
             * Change **Source** to something more restrictive, e.g.:
               * A specific CIDR like `10.0.0.0/16` (your internal network),
               * Or a specific IP such as `203.0.113.10/32` (admin workstation).
        3. If you do not need any inbound traffic via the default SG:
           * Remove **all** inbound rules, leaving the inbound rules list **empty**.
        4. Click **Save rules**.

        Repeat this for the default Security Group in **every VPC** in your account/region.

        ***

        ## 4. Ensure new resources don’t rely on the default SG for inbound access

        1. When launching new EC2 instances:
           * In **Step: Configure Security Group** (or equivalent in the console wizard), **do not select** the default Security Group for publicly exposed services.
           * Instead, create/choose a dedicated SG with only the specific ports and IP ranges needed.
        2. For existing instances that rely on the default SG for inbound access:
           * Create a **new Security Group** with least-privilege rules.
           * Attach the new SG to the instance:
             * Select the instance → **Actions** → **Security** → **Change security groups**.
             * Add the new SG and (optionally) remove the default SG.
             * Click **Apply**.

        ***

        ## 5. (Optional) Check outbound rules on default SG

        Best practice is to also restrict outbound where needed:

        1. Select the default Security Group.
        2. Open **Outbound rules**.
        3. Click **Edit outbound rules**.
        4. Remove or tighten any `0.0.0.0/0` or `::/0` rules if your policy requires restricted egress.
        5. Click **Save rules**.

        ***

        By completing the above steps for each default Security Group in each VPC, you will have removed unrestricted inbound access while keeping the default SG itself (which cannot be deleted).
      </Accordion>

      <Accordion title="Using CLI">
        Below are concise, step‑by‑step AWS CLI instructions to lock down default Security Groups so they don’t allow unrestricted (0.0.0.0/0 or ::/0) inbound access.

        ***

        ### 1. Identify all default Security Groups

        ```bash theme={null}
        aws ec2 describe-security-groups \
          --filters Name=group-name,Values=default \
          --query 'SecurityGroups[*].{GroupId:GroupId,GroupName:GroupName,VpcId:VpcId}' \
          --output table
        ```

        Keep the `GroupId` values; you’ll need them for the next steps.

        ***

        ### 2. Review current inbound rules for a specific default Security Group

        Replace `<sg-id>` with the Security Group ID:

        ```bash theme={null}
        aws ec2 describe-security-groups \
          --group-ids <sg-id> \
          --query 'SecurityGroups[0].IpPermissions'
        ```

        Look for any rules where:

        * `IpRanges[].CidrIp` is `0.0.0.0/0`
        * `Ipv6Ranges[].CidrIpv6` is `::/0`

        ***

        ### 3. Revoke unrestricted IPv4 inbound rules

        This example revokes **all** IPv4 inbound rules from the default SG that are open to `0.0.0.0/0`.\
        First get those rules in a form the CLI can accept:

        ```bash theme={null}
        aws ec2 describe-security-groups \
          --group-ids <sg-id> \
          --query 'SecurityGroups[0].IpPermissions[?contains(IpRanges[].CidrIp, `0.0.0.0/0`)]' \
          > ipv4-open-rules.json
        ```

        If `ipv4-open-rules.json` is not empty, run:

        ```bash theme={null}
        aws ec2 revoke-security-group-ingress \
          --group-id <sg-id> \
          --ip-permissions file://ipv4-open-rules.json
        ```

        ***

        ### 4. Revoke unrestricted IPv6 inbound rules

        Similarly for IPv6 (`::/0`):

        ```bash theme={null}
        aws ec2 describe-security-groups \
          --group-ids <sg-id> \
          --query 'SecurityGroups[0].IpPermissions[?contains(Ipv6Ranges[].CidrIpv6, `::/0`)]' \
          > ipv6-open-rules.json
        ```

        If `ipv6-open-rules.json` is not empty:

        ```bash theme={null}
        aws ec2 revoke-security-group-ingress \
          --group-id <sg-id> \
          --ip-permissions file://ipv6-open-rules.json
        ```

        ***

        ### 5. Repeat for all default Security Groups

        Loop over all default SGs in a shell (bash example):

        ```bash theme={null}
        for SG in $(aws ec2 describe-security-groups \
                      --filters Name=group-name,Values=default \
                      --query 'SecurityGroups[].GroupId' \
                      --output text); do
          echo "Processing $SG"

          aws ec2 describe-security-groups \
            --group-ids $SG \
            --query 'SecurityGroups[0].IpPermissions[?contains(IpRanges[].CidrIp, `0.0.0.0/0`)]' \
            > ipv4-open-rules.json

          if [ -s ipv4-open-rules.json ]; then
            aws ec2 revoke-security-group-ingress \
              --group-id $SG \
              --ip-permissions file://ipv4-open-rules.json
          fi

          aws ec2 describe-security-groups \
            --group-ids $SG \
            --query 'SecurityGroups[0].IpPermissions[?contains(Ipv6Ranges[].CidrIpv6, `::/0`)]' \
            > ipv6-open-rules.json

          if [ -s ipv6-open-rules.json ]; then
            aws ec2 revoke-security-group-ingress \
              --group-id $SG \
              --ip-permissions file://ipv6-open-rules.json
          fi
        done
        ```

        ***

        ### 6. (Optional) Add restricted inbound rules instead

        Example: allow SSH only from a corporate CIDR (replace `203.0.113.0/24`):

        ```bash theme={null}
        aws ec2 authorize-security-group-ingress \
          --group-id <sg-id> \
          --ip-permissions '[
            {
              "IpProtocol": "tcp",
              "FromPort": 22,
              "ToPort": 22,
              "IpRanges": [{"CidrIp": "203.0.113.0/24","Description": "SSH from corp"}]
            }
          ]'
        ```

        This ensures the default Security Groups no longer allow unrestricted inbound access.
      </Accordion>

      <Accordion title="Using Python">
        Below is a step‑by‑step approach plus a ready‑to‑run Python (boto3) script that:

        1. Finds all **default** security groups in all regions.
        2. Removes any **inbound rules** that allow unrestricted access (0.0.0.0/0 or ::/0).

        ***

        ## Prerequisites

        * AWS credentials configured (e.g., `~/.aws/credentials` or environment variables).
        * Python 3.x
        * `boto3` installed:
          ```bash theme={null}
          pip install boto3
          ```

        ***

        ## Remediation Logic

        1. Enumerate all AWS regions.
        2. For each region:
           * Get all security groups where `GroupName == 'default'`.
           * Inspect `IpPermissions` (inbound rules).
           * For each permission, check if any of:
             * `IpRanges` has `CidrIp == '0.0.0.0/0'`
             * `Ipv6Ranges` has `CidrIpv6 == '::/0'`
           * Build a permission structure that includes **only** the unrestricted ranges to be removed.
           * Call `revoke_security_group_ingress` with those specific ranges.

        ***

        ## Python Script (boto3)

        ```python theme={null}
        import boto3
        from botocore.exceptions import ClientError

        def get_all_regions():
            ec2 = boto3.client('ec2')
            regions = ec2.describe_regions(AllRegions=True)['Regions']
            return [r['RegionName'] for r in regions if r['OptInStatus'] in ('opt-in-not-required', 'opted-in')]

        def remove_unrestricted_inbound_from_default_sg(region):
            ec2 = boto3.client('ec2', region_name=region)
            print(f"\n[Region: {region}]")

            try:
                # Get all default security groups
                response = ec2.describe_security_groups(
                    Filters=[
                        {'Name': 'group-name', 'Values': ['default']}
                    ]
                )
                sgs = response['SecurityGroups']
                if not sgs:
                    print("  No default security groups found.")
                    return

                for sg in sgs:
                    group_id = sg['GroupId']
                    group_name = sg.get('GroupName', '')
                    print(f"  Checking SG: {group_id} ({group_name})")

                    ip_permissions_to_revoke = []

                    for perm in sg.get('IpPermissions', []):
                        new_perm = {
                            'IpProtocol': perm['IpProtocol'],
                            'FromPort': perm.get('FromPort'),
                            'ToPort': perm.get('ToPort'),
                            'IpRanges': [],
                            'Ipv6Ranges': [],
                            'UserIdGroupPairs': [],
                            'PrefixListIds': []
                        }

                        # Only pick the "unrestricted" IPv4 ranges
                        for r in perm.get('IpRanges', []):
                            if r.get('CidrIp') == '0.0.0.0/0':
                                new_perm['IpRanges'].append(r)

                        # Only pick the "unrestricted" IPv6 ranges
                        for r in perm.get('Ipv6Ranges', []):
                            if r.get('CidrIpv6') == '::/0':
                                new_perm['Ipv6Ranges'].append(r)

                        # If this permission has any unrestricted ranges, queue it to revoke
                        if new_perm['IpRanges'] or new_perm['Ipv6Ranges']:
                            # Clean empty fields because boto3 can complain about them
                            new_perm = {k: v for k, v in new_perm.items() if v not in (None, [], '')}
                            ip_permissions_to_revoke.append(new_perm)

                    if ip_permissions_to_revoke:
                        print(f"    Revoking unrestricted ingress from SG {group_id} ...")
                        try:
                            ec2.revoke_security_group_ingress(
                                GroupId=group_id,
                                IpPermissions=ip_permissions_to_revoke
                            )
                            print("    Done.")
                        except ClientError as e:
                            print(f"    ERROR revoking rules for {group_id}: {e}")
                    else:
                        print("    No unrestricted inbound rules found.")

            except ClientError as e:
                print(f"  ERROR describing SGs in {region}: {e}")

        def main():
            regions = get_all_regions()
            for region in regions:
                remove_unrestricted_inbound_from_default_sg(region)

        if __name__ == "__main__":
            main()
        ```

        ***

        ## How to Run

        1. Save as `fix_default_sg_unrestricted.py`.
        2. Run:
           ```bash theme={null}
           python fix_default_sg_unrestricted.py
           ```
        3. Verify by checking default security groups in the AWS Console or via:
           ```bash theme={null}
           aws ec2 describe-security-groups --group-names default --region <region>
           ```

        This script only removes **unrestricted inbound** from default security groups and leaves other (more specific) rules intact.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "aws_default_security_group" "default_sg" {
          # Substitute YOUR_VPC_ID with the ID of the VPC whose default SG you are remediating
          vpc_id = "YOUR_VPC_ID"

          # REMOVE all ingress rules to avoid unrestricted inbound access
          # If specific inbound access is required, define only those ports/CIDR blocks explicitly.
          ingress = []

          # Example: allow all outbound traffic (adjust if your policy is stricter)
          egress {
            from_port   = 0
            to_port     = 0
            protocol    = "-1"
            cidr_blocks = ["0.0.0.0/0"]
            ipv6_cidr_blocks = ["::/0"]
          }

          tags = {
            Name = "default-security-group-YOUR_VPC_ID"
          }
        }
        ```

        This configuration manages the existing default security group in-place (no replacement of the SG itself; Terraform will just remove any existing unrestricted ingress rules).

        Verification: `terraform plan` should show all existing `ingress` rules on the default security group being removed (or replaced with the empty set) and only the specified `egress` rule(s) present.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
