Some time ago I was looking for a solution to find unused/unattached security groups within an AWS environment. Unfortunately I haven’t found an easy way to do it, except selecting all of them and trying to press delete to see notification on the ones which can’t be removed. I tried to find any dependencies to determine groups in-use and finally I found it. If security group isn’t attached to any network interface it is probably unused. Why probably? Because if you’ve a launch configuration (assigned to an auto scaling group) with defined security group, a group won’t be attached to a network interface until there aren’t available EC2 instances. If desired capacity of auto scaling group is equal to 0, you’ll be able to remove a group which is theoretically in-use.
I created a script, which allows you to scan all region whenever you want.
- sg-scanner is available on GitHub
- if you find any issues please report them on GitHub issues section
- if you’ve any features requests please ask for them also on GitHub
This tool is written in Python and it should work with versions 2.x and 3.x.
- Python 2.x or 3.x
- boto3 – AWS SDK for Python
- argparse – parser for CLI options & arguments
- tabulate – to make output nice 🙂
I tested it under Windows 10 and Ubuntu 16.04, but it should also work on other distros. Make sure you’ve Python and all required libs installed and you’re ready to go!
How it looks like & Use cases
You can use it on your EC2 instance (using an IAM role) or from your local PC (using AWS Access Key and Secret Key). I strongly recommend not to use it from an EC2 instance with AWS credentials because it isn’t really a good practice. You can find a policy with defined minimum required permission in repository – sgscanner-policy.json.
There are two scanning scenarios:
- unattached – which finds security groups that aren’t binded to any AWS service
- unsecure – which finds security groups with ports open from 0.0.0.0/0 CIDR
If a group isn’t attached to any network interface, it’ll be marked as unused. Generally, all security groups binded to an AWS Services such as: EC2, RDS, Lambda, Load Balancers, WorkSpaces, AppStream and more, must be attached to network interface.
General parameters overview:
$ python sgscanner.py REGION MODE --accesskey="youAccessKey" --secretkey="yourSecretKey" --ignoreports=80,443
- region – AWS region e.g “eu-west-1“
- mode – scanning scenario e.g “unattached“, “unsecure“
- –accesskey (optional) – access key of your AWS user
- –secretkey (optional) – secret key of your AWS user
- –ignoreports (optional) – list of ports that should be ignored while scanning for unsecure groups
Example of scanning eu-west-1 region for unattached groups:
$ python sgscanner.py eu-west-1 unattached --accesskey="ABC" --secretkey="123"
Example of scanning eu-west-1 region for unsecure groups:
$ python sgscanner.py eu-west-1 unsecure --accesskey="ABC" --secretkey="123"
$ python sgscanner.py eu-west-1 unsecure --accesskey="ABC" --secretkey="123" --ignoreports=80,443
As you can see ports 80 and 443 aren’t part of the output. There is one exception: if ports passed into –ignoreports argument are a part of port range, then those ports won’t be skipped. For example, if you add port 500 to ignore list and security group has a rule, which allows for port range 450-550, it’ll show as a part of the output:
and that’s all!
As you can see, it’s pretty simple tool, but it can be really useful. You can filter output using grep or select-string -pattern. I’m going to add filtering by any IP address (not only 0.0.0.0/0), and maybe I’ll add export to CSV function as well 🙂 .