我很难过滤AWS CLI描述安全组输出
目标:使用cidr 0.0.0.0/0 在端口22上查找所有具有入口规则的SG
Amazons自己的文档提供了一个例子,但指出他们的查询有一个限制,即它将首先过滤端口22的整个数据集,然后过滤0.0.0.0/0的整个数据集中。这意味着具有以下规则的SG仍将触发:
ingress 22 sg-12345678
ingress 443 0.0.0.0/0
这完全违背了过滤的目的,我甚至不知道亚马逊为什么在这个例子中提供标题为"描述有特定规则的安全组"的
路由1:aws-cli查询,然后jq
这条路线是基于我在这里发现的:https://github.com/aws/aws-cli/issues/971
aws ec2 describe-security-groups --output json --query 'SecurityGroups[*].[GroupName,GroupId,IpPermissions[?ToPort==`22`].[IpRanges[?CidrIp==`0.0.0.0/0`]]]'
它提供了所有安全组的列表,但显示了22个0.0.0.0/0的任何SG的嵌套数据(并成功忽略了其他端口的任何0.0.0.0/0ACL)。在下面的输出中,SG1是我感兴趣的,SG2/SG3需要过滤掉。
[
[
"SG 1",
"sg-11111111",
[
[
[
{
"CidrIp": "0.0.0.0/0"
}
]
]
]
],
[
"SG 2",
"sg-22222222",
[
[
[]
]
]
],
[
"SG 3",
"sg-33333333",
[]
]
]
这是一个很好的第一步,因为我已经消除了与端口22无关的0.0.0.0/0 ACL。但是,当我试图运行jq来简单地删除具有空数据集的条目时,我遇到了困难,因为所有的键都被剥离了。
- 当我试图在嵌套部分中进行更深的选择时,我最终会出现错误,比如无法迭代null
- 如果我尝试使用contains,我会一无所获,所以我甚至不确定哪里出了问题
路由2:jq未查询CLI输出
我从一开始就无法通过使用jq来摆脱原始AWS示例的缺陷,在jq中,我可以首先查询包含端口22的所有SG,然后查询0.0.0.0/0的任何ACL,这当然会给我带来误报。由于jq的流性质,我还没有弄清楚如何只在与条件A相关的项目上检查条件A(端口22),然后检查条件B(0.0.0.0/0)。
这里是2个SG的一些经过净化的原始CLI输出,同样,我需要在不触发第二个的假阳性的情况下获得第一个
{
"SecurityGroups": [
{
"Description": "SG 1",
"IpPermissions": [
{
"PrefixListIds": [],
"FromPort": 22,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"ToPort": 22,
"IpProtocol": "tcp",
"UserIdGroupPairs": [],
"Ipv6Ranges": []
}
],
"GroupName": "SG 1",
"VpcId": "vpc-12345678",
"OwnerId": "1234567890",
"GroupId": "sg-11111111"
},
{
"Description": "SG 2",
"IpPermissions": [
{
"PrefixListIds": [],
"FromPort": 22,
"IpRanges": [],
"ToPort": 22,
"IpProtocol": "tcp",
"UserIdGroupPairs": [
{
"UserId": "1234567890",
"GroupId": "sg-abcdefab"
}
],
"Ipv6Ranges": []
},
{
"PrefixListIds": [],
"FromPort": 443,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"ToPort": 443,
"IpProtocol": "tcp",
"UserIdGroupPairs": [],
"Ipv6Ranges": []
}
],
"GroupName": "SG 2",
"VpcId": "vpc-12345678",
"OwnerId": "1234567890",
"GroupId": "sg-22222222"
}
]
}
您需要使用高级JMESPath条件。查看下面的cli命令是否满足您的要求。
aws ec2 describe-security-groups
--filters "Name=ip-permission.to-port,Values=22"
--query 'SecurityGroups[?IpPermissions[?ToPort==`22` && contains(IpRanges[].CidrIp, `0.0.0.0/0`)]].{GroupId: GroupId, GroupName: GroupName}'
--output json
--region us-east-1
这里有一个jq过滤器,它将只返回IpPermission为FromPort=22和IpRange CidrIp为"0.0.0.0/0"的SecurityGroups:
.SecurityGroups[]
| select(.IpPermissions[] | .FromPort == 22 and .IpRanges[].CidrIp == "0.0.0.0/0")
样本运行(假设filter.jq
中有过滤器,data.json
中有数据)
$ jq -M -f filter.jq data.json
{
"Description": "SG 1",
"IpPermissions": [
{
"PrefixListIds": [],
"FromPort": 22,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"ToPort": 22,
"IpProtocol": "tcp",
"UserIdGroupPairs": [],
"Ipv6Ranges": []
}
],
"GroupName": "SG 1",
"VpcId": "vpc-12345678",
"OwnerId": "1234567890",
"GroupId": "sg-11111111"
}
在jqplay.org 上在线试用
jq用空嵌套数据过滤安全组的解决方案:
aws ec2 describe-security-groups --output json --query 'SecurityGroups[*].[GroupName,GroupId,IpPermissions[?ToPort==`22`]
.[IpRanges[?CidrIp==`0.0.0.0/0`]]]' | jq 'map(select(.[2] | flatten | length > 0))'
输出:
[
[
"SG 1",
"sg-11111111",
[
[
[
{
"CidrIp": "0.0.0.0/0"
}
]
]
]
]
]