2

Found some similar questions on here but none that specifically answered this question. I have several security groups that have rules that allow all traffic from all source IPs. I would like to concoct a simple CLI command that grabs these for me.

After scouring some sources, I thought for sure this command would work:

$ aws ec2 describe-security-groups
    --filters "Name=ip-permission.protocol,Values=-1"
    --query 'SecurityGroups[?length(IpPermissions[?IpProtocol==`-1` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`]'

[]

However, this returns an empty list. In fact, narrowing it down to just the first condition of the query returns an empty list

$ aws ec2 describe-security-groups
    --filters "Name=ip-permission.protocol,Values=-1"
    --query 'SecurityGroups[?length(IpPermissions[?IpProtocol==`-1`]) > `0`]'

[]

even though taking out the above query (which I thought matches the filter) returns several security groups:

aws ec2 describe-security-groups
    --filters "Name=ip-permission.protocol,Values=-1"

[sg-1, sg-2, sg-3 ...]

What am I not understanding? Thanks in advance.

UPDATE

This new query is closer. It is retrieving every security group that has both a rule that allows all protocols and a rule that allows traffic from all IPs. However, the security groups currently being retrieved do not explicitly have those two conditions in the same rule as I'd like.

aws ec2 describe-security-groups
    --filters "Name=ip-permission.protocol,Values=-1"
    --query "SecurityGroups[?IpPermissions[?IpProtocol == '-1']] |
        [?length(IpPermissions[?contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`]"

Also, I figure it would be helpful to show the JSON object for those unfamiliar with its structure. You can find it on this page towards the bottom

Peter
  • 448
  • 2
  • 12

2 Answers2

3

Turns out, my original command was actually very close. I took out the logic with the length() function and now it works.

aws ec2 describe-security-groups
    --filters "Name=ip-permission.protocol,Values=-1"
    --query "SecurityGroups[?IpPermissions[?IpProtocol == '-1' &&
      contains(IpRanges[].CidrIp,'0.0.0.0/0')]].GroupId"

Hope this helps someone in the future.

Peter
  • 448
  • 2
  • 12
0

You could do this via aws ec2 but why not just use Trusted Advisor which already checks for bad security groups.

You can also access its checks via the CLI using the describe-trusted-advisor-check-summaries command.

These checks are free for all accounts.

Chris Williams
  • 23,842
  • 4
  • 14
  • 39
  • 1
    Good advice, but this command is actually part of a larger script that I'm developing that detaches these security groups from any instances and replaces them with a security group that has stricter rules. – Peter Jun 04 '20 at 16:53
  • 1
    Ah ok, might I suggest if this is not a 1 time script you also look at https://docs.aws.amazon.com/config/latest/developerguide/ec2-security-group-attached-to-eni.html. With a Lambda function to retrospecitively fix this if a bad security group is attached. This will apply close to the attachment as oppose to a intervalled script – Chris Williams Jun 04 '20 at 17:01
  • 1
    Cool, didn't know about that one, thanks! This was actually going to be a one time script (but use it in several AWS environments). After I got the SGs in the state I wanted them in I was going to use this config rule to keep things in order: https://docs.aws.amazon.com/config/latest/developerguide/vpc-sg-open-only-to-authorized-ports.html – Peter Jun 04 '20 at 17:15