筛选具有特定端口和IP ACL的安全组的AWS CLI输出



我很难过滤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"
}
]
]
]
]
]

最新更新