云服务器安全组规则优先级的机制记录

一条规则写在最前面,把后面的全挡了。这次云服务器安全组规则优先级的排查,起点不是报错信息,是控制台上那几行看着像队列的东西。

机器在杭州区,一台 ECS,对外接口只开了 22、80、443 三个口。

上周有两个地址段在扫这个接口的探测路径,日志里一分钟几十条 404,值班的人想把来源先挡掉。

规则加完,它在列表里排到了第一行。回车之后 443 全断,公司自己那条放行也一起失效。

第一反应是顺序问题:拒绝排在第一条,先命中先返回,后面的放行自然轮不到。

这个解释在 iptables 里是成立的。放在安全组上,它只对了一半。

一、现象里的第一个误导:列表位置

控制台的规则列表按优先级从小到大排,第一行就是数字最小的那条。

"排在最前面"和"优先级最高"在界面上长得一样。看的人容易把显示顺序当成因果关系。

真正决定谁先生效的是那个数字,列表只是把数字排了一遍。

这一点会带来一个很具体的偏差:改动方式变成拖顺序,而不是改数字。

拖到第一行,数字跟着变成 1。看起来位置变了,实际是数字变了。

那天加的这条 Drop 就是数字 1。它挡住后面的原因,一半在这个数字,另一半在源地址那一栏。

二、云服务器安全组规则优先级,在三层里指三件事

有优先级的层看数字,只有放行的层不看位置,iptables 看行号,三种判据不能互相搬。

安全组是挂在实例网卡外侧的一组有状态过滤规则,决定哪些包能被送到这块网卡。

"有状态"管的是回程,放过去的连接,回来的包自动放行,不必另写一条。"网卡外侧"管的是位置,包还没进协议栈,先在这里被筛一遍。

按这层的意思,规则之间要比出先后,靠的是优先级数字。数字小的先判,判中即停,后面的不再进入匹配。

阿里云的安全组走这个模型,入方向和出方向各一套,每条规则带一个 1 到 100 的优先级。

AWS 的安全组走另一个模型,只有允许,没有拒绝,所有规则一起评估,评估完给一个结论。

iptables 走第三个模型,规则按写入的行号排。第一条命中就返回,后面的不再看。

三种模型放在一起,"顺序"这个词就散了。它在第一层是数字,在第二层不存在,在第三层是行号。

三、把规则打成字段,位置不在里面

查出来的规则只有字段,没有位置这一项,界面上的先后是它按优先级排出来的结果。

一条规则在这层由三个字段决定:优先级、策略、源地址。端口和协议是筛选条件,不是判据。

复制代码
aliyun ecs DescribeSecurityGroupAttribute \
  --RegionId cn-hangzhou \
  --SecurityGroupId sg-bp1a2b3c \
  --Direction ingress --output json
# {
#   "Permissions": {"Permission": [
#     {"Priority": 1, "Policy": "Drop",   "IpProtocol": "tcp",
#      "PortRange": "443/443", "SourceCidrIp": "0.0.0.0/0"},
#     {"Priority": 100, "Policy": "Accept", "IpProtocol": "tcp",
#      "PortRange": "443/443", "SourceCidrIp": "203.0.113.0/24"},
#     {"Priority": 100, "Policy": "Accept", "IpProtocol": "tcp",
#      "PortRange": "22/22",   "SourceCidrIp": "198.51.100.7/32"}
#   ]}
# }

第一条是优先级 1 的 Drop,源写成 0.0.0.0/0,端口 443。

这个源覆盖所有地址,对 443 上的一切流量都成立,判断在第一行就结束了。

第二条是优先级 100 的 Accept,源 203.0.113.0/24,公司自己那条。它排在下一位,永远轮不到。

把 Drop 的源改成 198.51.100.9/32,优先级仍是 1,203.0.113.0/24 就能过去,被挡的只有那一个地址。

这一组对比把位置摘了出去。挡不挡,看的是那条规则匹配面有多大,与它写在第几行没有关系。

匹配面这个词在这里能量出来,源是 /32 就只管一个地址,源是 /0 就管全部。当晚那条规则的匹配面是全部,优先级又最小,两件事叠在一起才成了全断。

四、换到只有放行的那一层,这句话写不出来

同一句"挡掉某个来源",在没有拒绝规则的那一层没有对应写法。

项目另一边还有一台 AWS 的机器,同一份规则思路搬过去,那条 Drop 就没有地方可写。控制台的入方向里没有拒绝这一项,只有允许。

复制代码
aws ec2 describe-security-groups \
  --group-ids sg-0a1b2c3d4e \
  --query 'SecurityGroups[].IpPermissions' --output json
# [
#   [
#     {"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443,
#      "IpRanges": [{"CidrIp": "203.0.113.0/24"}]},
#     {"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22,
#      "IpRanges": [{"CidrIp": "198.51.100.7/32"}]}
#   ]
# ]

数组里只有协议、端口、源,没有策略字段,也没有优先级字段。

这一层能表达的只有允许谁进来。想挡住一段地址,做法是干脆不放行,而不是写一条拒绝。

"拒绝排在第一条"在这里无从发生,不是被排到了后面,是根本不存在这条规则。

网卡上挂多张组的时候,判据是并集。任意一张组放行,包就进来,组与组之间没有先后。

复制代码
aws ec2 describe-network-interfaces \
  --network-interface-ids eni-0a1b2c3d4e \
  --query 'NetworkInterfaces[].Groups' --output json
# [
#   [
#     {"GroupName": "web-tier", "GroupId": "sg-0a1b2c3d4e"},
#     {"GroupName": "bastion",  "GroupId": "sg-0f6e5d4c3b"}
#   ]
# ]

两张组挂在一起,暴露面等于两张组的放行范围相加。

组内规则之间同样没有先后,因为评估时全部一起看,不存在先命中这一说。

这一层能调的只有范围本身。收窄一条放行、少挂一张组,都是改集合,不是改位置。

五、行序真正生效的地方

行号是那种"写在前面就一定先生效"的判据,iptables 用的就是它。

复制代码
iptables -S INPUT
# -P INPUT ACCEPT
# -A INPUT -p tcp -m tcp --dport 443 -j DROP
# -A INPUT -s 203.0.113.0/24 -p tcp -m tcp --dport 443 -j ACCEPT
# -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

第一条 DROP 443 写在最前,第二条对 203.0.113.0/24 的 ACCEPT 就永远收不到包。

两条的顺序反了才是原意。改动落在链上的位置,用 -I INPUT 2 插到第二条之前,规则内容一个字不用动。

这一层看起来最像队列,因为它就是按行号逐条走,命中即停。

团队里那句"第一条挡后面"大概来自这台机器的 iptables。同一个项目两种环境,两套判据,句子从一处搬到另一处,只剩一半成立。

同一句在两种层上的命运不同:有优先级的层靠数字仍成立,靠位置不成立,只有放行的层整句失效。

六、上线前怎么定规则

顺序这个词在定规则时要先落到判据上,判据不同,同一份意图的写法完全不同。

有优先级字段的层,规则集要按数字读,不是按界面顺序读。最宽的那条排在数字最大的一位,让它判在具体规则之后。

没有优先级字段的层,位置不表达任何意图,要挡一段地址只能把放行范围收窄到不含它。

同一台机器挂多张组、多张网卡时,暴露面按并集算。任意一处开着的口,就是对外开着的口。

规则落地前的那一遍核对,是把每条的源范围与端口抄成一行,与业务清单对,0.0.0.0/0 那几条单独看,它们决定的是整台机器的暴露面。

那天真正的问题在源那一栏,不在它排第几行。顺序是一个更容易被记住的替罪羊。

判断一套安全组规则是否可用,看的是每条规则的匹配面,以及它与业务清单对不对得上。列表里的名次不提供这个信息。

相关推荐
KaiwuDB2 小时前
KaiwuDB 运维实战06:数据库备份与恢复:从理论到实战
运维·数据库·时序数据库·kaiwudb
youce_1232 小时前
测速跑满,但是打开网页、刷视频总转圈?问题不在带宽
网络·智能路由器
智购科技自动售货机厂家3 小时前
让AI经营自动售货机:从Project Vend看工具权限与业务规则~YH
大数据·服务器·单片机·嵌入式硬件·深度学习
jnrjian3 小时前
delete file shell 让 AI 写脚本
服务器·开发语言
数字新视界3 小时前
空调控制器AIRC800的智能化管理与应用实践
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
知已难寻3 小时前
01 · OpenStack的认证管理 Keystone
运维·服务器·云原生·云计算·openstack
ai_xiaogui3 小时前
私有化部署大模型实战:PanelAI 一键搭建、Token 计费与多用户隔离
运维·私有化部署·大模型部署·大模型 token 计费·api key 统一管理·多用户实例隔离·应用市场一键部署
企鹅侠客3 小时前
Linux CPU 负载平均值(Load Average)详解:从原理到实践
linux·运维·服务器·服务器负载
易点云徐源4 小时前
HP 暗影精灵 PRO 16 安装双系统后,开机直接进入 Windows,按 F9 才能进入 Ubuntu:GRUB 菜单不显示的处理方法
linux·运维·ubuntu