Today, I was reminded of the rich content stored in AWS Config and how easily it can reveal so much about an AWS Organisation across one or many accounts.
The challenge
After some network plumbing changes, it was time to audit some security groups to determine if old CIDR blocks had been left around and needed to be cleaned up. Now of course, we could approach an issue like this as follows.
Describe Security Groups and Save Output
Run the following AWS CLI command to fetch all security groups in a region and save the output to a JSON file:
aws ec2 describe-security-groups --region <your-region> --output json > security-groups.json
Search the Output
With the JSON saved, you can use tools like jq
to search within the JSON data for security groups that include 10.2.55.0/22
in their allowed IP ranges.
jq '.SecurityGroups[] | select(.IpPermissions[].IpRanges[]?.CidrIp == "10.2.55.0/22")' security-groups.json
Explanation:
SecurityGroups[]
: Iterates over each security group in the JSON output.select(.IpPermissions[].IpRanges[]?.CidrIp == "10.2.55.0/22")
: Checks if any of theCidrIp
entries inIpPermissions
match10.2.55.0/22
.
Great, so that would work. However, what if we had 10 AWS Accounts, 100, or even 1000? That is a bit of a push to do individually.
If you’ve followed best practices and used AWS Control Tower for account vending or even the AWS Landing Zone Accelerator solution, you will have a magical tool called an AWS Config Aggregator, which we will use to perform some magic.
Could you give me some aggregation?
To achieve the same result but at scale, we can use AWS Config with an aggregator to extract information about security groups across an organisation instead of executing AWS CLI commands on every account.
Here’s how you can use AWS Config with an advanced query to retrieve security group rules:
Step 1: Run the Advanced Query on the Config Aggregator
Replace <ConfigAggregatorName>
with the name of your AWS Config aggregator. The query will retrieve information about security groups, including their IP permissions.
$ aws configservice select-aggregate-resource-config \
--configuration-aggregator-name <ConfigAggregatorName> \
--expression "
SELECT
accountId,
resourceId,
resourceName,
resourceType,
configuration.ipPermissions
WHERE
resourceType = 'AWS::EC2::SecurityGroup'
" \
--output json > security-group-config.json
Now before we move on, lets just recap on what we have just retrieved. We now have a JSON file that contains every single security group ipPermissions output across every account in our AWS Organisation! Imagine what else we could retrieve, you just need to go digging. Back to the task at hand.
Step 2: Filter for Specific IP Ranges Locally
The above command will save the JSON output to security-group-config.json
. Once you have this JSON file, you can use a tool like jq
to filter the results locally for any specific IP ranges, such as 10.2.55.0/22
.
For example:
$ jq -r '.Results[] | fromjson | select(any(.configuration.ipPermissions[]?.ipRanges[]?; . == "10.2.55.0/22")) | "\(.accountId) \(.resourceId)"' security-group-config.json
123456789012 sg-00123345dfasdas8d
098765432109 sg-00125543dfasdads9
...
...
jq
command so I can go find out who owns that AWS accountid!If you just want a count of how much of a larger issue you have then just pipe to wc
jq -r '.Results[] | fromjson | select(any(.configuration.ipPermissions[]?.ipRanges[]?; . == "10.2.55.0/22")) | "\(.accountId) \(.resourceId)"' security-group-config.json | wc -l
165
jq
is such a powerful tool for exploring JSON files so start learning it today!
Summary
This article offered a glimpse into the potential of AWS Config Aggregator and the wealth of insights it provides about your resources. With so many opportunities for deeper understanding, it's a tool worth revisiting.
Dive into the resource schemas and data available in your Config Aggregator today!
I hope this has been helpful.
Cheers!