Here is an example security group that has inbound port 22 open from 0.0.0.0/0 and port 80 open from 0.0.0.0/0.
{
"SecurityGroups": [
{
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"UserIdGroupPairs": []
}
],
"Description": "VPC Security Group",
"Tags": [
{
"Value": "some-app",
"Key": "Name"
}
],
"IpPermissions": [
{
"ToPort": 22,
"IpProtocol": "tcp",
"IpRanges": [],
"UserIdGroupPairs": [
{
"UserId": "xxxxxx",
"GroupId": "sg-123456"
}
],
"FromPort": 22
},
{
"ToPort": 80,
"IpProtocol": "tcp",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"UserIdGroupPairs": [],
"FromPort": 80
}
],
"GroupName": "some-app",
"VpcId": "vpc-xxxx",
"OwnerId": "xxxxxx",
"GroupId": "sg-123456"
}
]
}
I want to get a table with all instances that have a security group rule matching (to-port 22 and from-cidr 0.0.0.0/0).
I have the following,
aws ec2 describe-security-groups --output table --filters "Name=ip-permission.to-port,Values=22" --query 'SecurityGroups[].[Tags[?Key==`Name`] | [0].Value, GroupName]'
This will create a table with the instance name in the left column and the security group in the right column that has inbound port 22.
However, the output doesn't tell me whether that is from 0.0.0.0/0 or from 10.0.1.0/24.
I tried adding a second filter "Name=ip-permission.cidr,Values=0.0.0.0/0"
aws ec2 describe-security-groups --output table --filters "Name=ip-permission.to-port,Values=22" "Name=ip-permission.cidr,Values=0.0.0.0/0" --query 'SecurityGroups[].[Tags[?Key==`Name`] | [0].Value, GroupName]'
But the filters are not matching inbound port 22 from 0.0.0.0/0 alone. It will also match the example security group above which has port 80 open from 0.0.0.0/0.
Is this a limitation of aws-cli
?
Are there any workarounds?
Sorry for the delay. This is not currently possible with the current --query
option. Essentially what's needed is the ability to "and" expressions together. I don't have an exact timeline and when this will be available, but eventually you'll be able to use &&
like this:
$ aws ec2 describe-security-groups --filters "Name=ip-permission.to-port,Values=22" \
--query 'SecurityGroups[?length(IpPermissions[?ToPort==`22` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupName: GroupName, TagName: Tags[?Key==`Name`].Value | [0]}' --output table
Marking this as a feature request and I'll update this PR once this has been implemented.
If this is known not to work and has been acknowledged by AWS not to work, then why is it listed as an example in the AWS documentation?
Why would you give an example in the documentation of a command that is known not to work? That makes no sense.
If you look at http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-security-groups.html, it states, "To describe security groups that have a specific rule (EC2-VPC only) This example uses filters to describe security groups that have a rule that allows SSH traffic (port 22) from all IP addresses (0.0.0.0/0). The output is filtered to display only the names of the security groups.
Command:
aws ec2 describe-security-groups --filters Name=ip-permission.from-port,Values=22 Name=ip-permission.to-port,Values=22 Name=ip-permission.cidr,Values='0.0.0.0/0' --query 'SecurityGroups[*].{Name:GroupName}'
"
But again, this is known not to work. So why is it listed in the documentation as an example, if it's known not to work?
Also not working, ip-permissions.protocol = icmp returns tcp values.... Even though you asked to only see icmp.
Bugged!
$ aws ec2 describe-security-groups --group-ids sg-XXXXXXXX --filter Name=ip-permission.protocol,Values=icmp --query 'SecurityGroups[].IpPermissions[].IpProtocol[]'
[
"tcp",
"tcp",
"tcp",
"tcp",
"icmp",
"tcp",
"tcp",
"tcp",
"tcp"
]
jackal242 probably not a bug it just doesn't work that way. I would have also expected as you did to only see icmp. First specifying a SG here effectively negates the filter. The filter is on descibe-security-groups so only shows those groups which have icmp in any rule. The query for 'SecurityGroups[].IpPermissions[].IpProtocol[]' show all the protocols in that set. If you look at the results of the first you likely see it returned a single security group which had many protocols/ports specified and then you asked it to show you all the protocols in that group.
Version 1.8.9 of the CLI now has support for "&&" expressions. The expression I referenced earlier now works. Let us know if there's any more questions.
aws ec2 describe-security-groups --group-id sg-XXXXXXX | grep "GroupName|FromPort|IpRanges|CidrIp"
In case somebody needs it this worked for me:
aws ec2 describe-security-groups --query 'SecurityGroups[*].[GroupName,GroupId,IpPermissions[?ToPort=="22"].[IpRanges[?CidrIp=="0.0.0.0/0"]]]'
@jdirausquin & @saurabhsri2015 : it doesn't work for me.
@prensoni0143 if you copied and pasted, be sure the quotation marks are there.
@jdirausquin : Yes. I received response as below:
$ aws ec2 describe-security-groups --query 'SecurityGroups[*].[GroupName,GroupId,IpPermissions[?ToPort=="22"].[IpRanges[?CidrIp=="0.0.0.0/0"]]]'
Row should have 1 elements, instead it has 0
how to get instance ids with respective groups for the above query
aws ec2 describe-security-groups --query 'SecurityGroups[].[GroupName,GroupId,IpPermissions[?ToPort=="22"].[IpRanges[?CidrIp=="0.0.0.0/0"]]]'
not working for me either.
Response I get is
"SecurityGroups[].[GroupName,GroupId,IpPermissions[?ToPort==22].[IpRanges[?CidrIp==0.0.0.0/0]]]"
I can see in the AWS console that I have at least one security group in my default region that has port 22 open for Inbound traffic, to 0.0.0.0/0
It works for me:
aws ec2 describe-security-groups --filters Name=ip-permission.from-port,Values=22 Name=ip-permission.to-port,Values=22 Name=ip-permission.cidr,Values='0.0.0.0/0' --query 'SecurityGroups[*].{Name:GroupName}' --o table
How can we filter out public ips as output for which port e,g 22 is open in inbound rule. I tried editing above command however in the output it is not showing ip addresses. Please help!
@bsagta asked:
Hi, @bsagta
Try the following expression from @jamesls:
aws ec2 describe-security-groups --filters "Name=ip-permission.to-port,Values=22" \
--query 'SecurityGroups[?length(IpPermissions[?ToPort==`22` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]) > `0`].{GroupName: GroupName, TagName: Tags[?Key==`Name`].Value | [0]}' --output table
The above works for me in the following two test case scenarios:
• Scenario 1: Create a new security group with only:
Inbound | SSH | TCP | 22 | 0.0.0.0/0
• Scenario 2: Edit an existing security group, then add and save a new rule:
Inbound | SSH | TCP | 22 | 0.0.0.0/0
This is based on comments from @jamesls:
Most helpful comment
In case somebody needs it this worked for me:
aws ec2 describe-security-groups --query 'SecurityGroups[*].[GroupName,GroupId,IpPermissions[?ToPort=="22"].[IpRanges[?CidrIp=="0.0.0.0/0"]]]'