<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-cloud-network-security-groups
description: >-
  Implement and audit cloud network security groups across AWS Security Groups,
  Azure NSGs, and GCP VPC Firewall Rules to enforce least-privilege network access,
  detect overly permissive rules, and harden network segmentation.
domain: cybersecurity
subdomain: cloud-security
tags:
  - aws
  - azure
  - gcp
  - security-groups
  - nsg
  - firewall-rules
  - network-security
  - vpc
  - segmentation
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1562.004"]
---

# Implementing Cloud Network Security Groups

## Overview

Cloud network security groups are the first line of defense for workload isolation.
Overly permissive rules — especially 0.0.0.0/0 ingress on management ports — are
consistently among the top findings in cloud security assessments. This skill covers
auditing and hardening AWS Security Groups, Azure NSGs, and GCP VPC Firewall Rules
with focus on eliminating broad ingress, enforcing segmentation, and monitoring rule
changes.

Mode: `[MODE: BLUE]` — Network security hardening.

## Prerequisites

| Requirement | Details |
|---|---|
| AWS CLI v2, Azure CLI, `gcloud` CLI configured | Required |
| AWS | `ec2:DescribeSecurityGroups`, `ec2:DescribeNetworkInterfaces` |
| Azure | `Microsoft.Network/networkSecurityGroups/read` |
| GCP | `compute.firewalls.list`, `compute.networks.list` |
| Python 3.10+ with `boto3` | Required |

## Key Concepts

### AWS Security Group Audit

```bash
# Find security groups with 0.0.0.0/0 ingress
aws ec2 describe-security-groups \
  --filters "Name=ip-permission.cidr,Values=0.0.0.0/0" \
  --query 'SecurityGroups[].{ID:GroupId,Name:GroupName,VPC:VpcId}' --output table

# Find SGs allowing all ports from 0.0.0.0/0
aws ec2 describe-security-groups --output json | jq '
  .SecurityGroups[] | select(.IpPermissions[] |
    select(.IpRanges[]?.CidrIp == "0.0.0.0/0" and .FromPort == null))
  | {GroupId, GroupName}'

# Find SGs with SSH (22) open to the world
aws ec2 describe-security-groups --filters \
  "Name=ip-permission.from-port,Values=22" \
  "Name=ip-permission.cidr,Values=0.0.0.0/0" \
  --query 'SecurityGroups[].{ID:GroupId,Name:GroupName}' --output table

# Find SGs with RDP (3389) open to the world
aws ec2 describe-security-groups --filters \
  "Name=ip-permission.from-port,Values=3389" \
  "Name=ip-permission.cidr,Values=0.0.0.0/0" \
  --query 'SecurityGroups[].{ID:GroupId,Name:GroupName}' --output table

# Find unused security groups
USED_SGS=$(aws ec2 describe-network-interfaces --query 'NetworkInterfaces[].Groups[].GroupId' --output text | tr '\t' '\n' | sort -u)
ALL_SGS=$(aws ec2 describe-security-groups --query 'SecurityGroups[].GroupId' --output text | tr '\t' '\n' | sort)
comm -23 <(echo "$ALL_SGS") <(echo "$USED_SGS")
```

### Azure NSG Audit

```bash
# Find NSGs with any/any allow rules
az network nsg list --output json | jq '
  .[] | select(.securityRules[] |
    select(.sourceAddressPrefix == "*" and .destinationPortRange == "*" and .access == "Allow"))
  | {name, resourceGroup}'

# Find NSGs allowing SSH from any source
az network nsg list --output json | jq '
  .[] | select(.securityRules[] |
    select(.sourceAddressPrefix == "*" and .destinationPortRange == "22" and .access == "Allow"))
  | {name, resourceGroup, rule: (.securityRules[] | select(.destinationPortRange == "22") | .name)}'

# List all NSG rules sorted by priority
az network nsg rule list --nsg-name $NSG_NAME --resource-group $RG \
  --query "sort_by(@, &priority)[].{Priority:priority,Name:name,Access:access,Direction:direction,Source:sourceAddressPrefix,DestPort:destinationPortRange}" \
  --output table

# Check NSG flow logs
az network watcher flow-log list --location $LOCATION --output table
```

### GCP VPC Firewall Rules

```bash
# Find firewall rules allowing 0.0.0.0/0 ingress
gcloud compute firewall-rules list \
  --filter="sourceRanges=0.0.0.0/0 AND direction=INGRESS" \
  --format="table(name,network,allowed[].map().firewall_rule().list(),sourceRanges)"

# Find rules allowing all protocols/ports
gcloud compute firewall-rules list \
  --filter="sourceRanges=0.0.0.0/0 AND allowed[0].IPProtocol=all" \
  --format="table(name,network,priority)"

# Find rules allowing SSH from anywhere
gcloud compute firewall-rules list \
  --filter="sourceRanges=0.0.0.0/0 AND allowed[].map().firewall_rule().list():tcp:22" \
  --format="table(name,network,priority,sourceRanges)"

# List disabled rules (may indicate drift)
gcloud compute firewall-rules list --filter="disabled=true" \
  --format="table(name,network,priority)"
```

## Workflow

### Step 1: Multi-Cloud Security Group Inventory

```bash
# AWS — count SGs per VPC
aws ec2 describe-security-groups --query 'SecurityGroups[].VpcId' --output text | tr '\t' '\n' | sort | uniq -c | sort -rn

# Azure — count NSGs per resource group
az network nsg list --query "[].resourceGroup" --output tsv | sort | uniq -c | sort -rn
```

### Step 2: Run Automated Audit

```bash
node scripts/agent.js --provider aws --output /tmp/nsg_audit.json
```

## Detection

```yaml
title: Cloud Network Security Groups Detection
id: 1494f09f-20ed-479f-8792-aaab8b45e38c
status: experimental
description: Detects suspicious activity related to implementing cloud network security groups techniques in cloud security context
logsource:
  product: aws
  service: cloudtrail
detection:
  selection:
    eventName: "*Unauthorized*"
  condition: selection
level: medium
tags:
  - attack.t1562.004
  - attack.credential_access
falsepositives:
  - Automated cloud infrastructure provisioning by approved CI/CD pipelines
```


**Detection Opportunities**

| Indicator | Source | Detection Logic |
|---|---|---|
| Cloud Network Security Groups Detection | aws | Sigma rule (medium) |
| ATT&CK Coverage | MITRE ATT&CK | T1562.004 |

## Verification

- [ ] No security groups with 0.0.0.0/0 on SSH (22), RDP (3389), or database ports
- [ ] All management access restricted to bastion/VPN CIDR ranges
- [ ] Unused security groups identified and removed
- [ ] NSG/firewall flow logs enabled for audit trail
- [ ] Default deny ingress enforced — explicit allow rules only
- [ ] Security group changes monitored via CloudTrail/Activity Log
- [ ] Network segmentation enforces workload isolation

## References

- [CIS AWS Foundations Benchmark — Networking](https://www.cisecurity.org/benchmark/amazon_web_services)
- [AWS Security Group Best Practices](https://docs.aws.amazon.com/vpc/latest/userguide/security-group-rules.html)
- [Azure NSG Security Rules](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview)
- [GCP VPC Firewall Rules](https://cloud.google.com/vpc/docs/firewalls)
