ACL工作原理:匹配顺序、隐式拒绝与路由器关系

ACL这东西,说白了就是一张规则表。路由器收到一个数据包,就拿着这张表从上往下比对。但这里头有几个关键点,我当年刚入行时也踩过坑,今天跟你好好聊聊。

ACL的匹配顺序:从上到下,命中即停

ACL的匹配规则很简单——顺序匹配,一旦命中就停止。路由器收到一个IP包,会从列表的第一条规则开始检查。如果匹配,就执行对应的动作(permit或deny),剩下的规则不再看。如果不匹配,就继续往下走。

举个例子,我曾在一次割接中遇到过这种情况:

access-list 100 permit ip 192.168.1.0 0.0.0.255 any
access-list 100 deny ip 192.168.1.100 0.0.0.0 any
access-list 100 permit ip any any

你发现问题了吗?第二条规则永远都不会生效。因为192.168.1.100属于192.168.1.0/24这个网段,第一条已经把它放行了。这就是顺序的重要性——精确的规则要放在前面,宽泛的规则放在后面。

⚠️ 注意:ACL一旦配置完成,新增的规则默认追加到末尾。如果你想在中间插入一条规则,必须删除整个ACL重新配置,或者使用序列号(sequence number)功能。我个人习惯在配置ACL时预留序列号间隔,比如用10、20、30,这样后期插入规则时就不用大动干戈。

隐式拒绝规则:看不见的守门员

这是ACL里最容易让人翻车的地方。每条ACL的末尾,都藏着一条看不见的规则——deny any any。也就是说,如果一个数据包跟ACL里所有规则都不匹配,路由器会直接把它丢掉。

我曾经帮一个客户排查网络故障,他们配了ACL允许特定网段访问服务器,但其他网段就是不通。他们检查了好几遍ACL,觉得没问题。我说:「你们ACL最后一条是什么?」他们一愣:「没有最后一条啊。」我说:「问题就在这——隐式拒绝已经把其他流量全拦了。」

核心要点:只要ACL被应用到接口上,无论你写了多少条permit,末尾都有一条隐式的deny any any。所以,如果你想让未被明确允许的流量通过,必须在ACL末尾显式添加一条 permit ip any any。

这里有个表格,帮你快速理解ACL的匹配逻辑:

匹配情况 结果 说明
匹配permit规则 允许通过 立即停止匹配,执行转发
匹配deny规则 丢弃数据包 立即停止匹配,执行丢弃
不匹配任何规则 丢弃数据包 触发隐式deny any any

ACL与路由器的关系:数据流的关卡

ACL不是独立存在的,它必须依附在路由器的某个位置才能发挥作用。我习惯把ACL理解成「关卡」——数据包经过路由器时,会在特定位置被检查。

对于入方向(inbound)ACL,数据包一进入接口就被检查。如果被deny,路由器直接丢弃,连路由表都不查。这样做的好处是节省CPU资源——不合规的流量根本进不来。

对于出方向(outbound)ACL,数据包先查路由表,确定从哪个接口出去,然后在离开接口前被检查。我建议你记住一个原则:能入向就别出向。为什么?因为入向ACL在数据包进入路由器时就过滤掉了,减少了后续的处理开销。

💡 实战建议:在部署ACL时,先想清楚数据流的走向。比如你要限制外部访问内部服务器,就在连接外网的接口上配入向ACL。如果你在出向配,数据包已经进了路由器,占用了路由表查询的资源,再丢掉就有点浪费了。

下面这张图,帮你理清ACL在路由器中的工作流程:

ACL在路由器中的工作流程 数据包到达接口 入向ACL检查 丢弃数据包 路由表查询 出向ACL检查 转发数据包 说明: 入向ACL在路由查询前执行,不合规流量直接被丢弃,节省CPU资源。 出向ACL在路由查询后执行,数据包已经占用了路由表查询的资源。

ACL的类型与适用场景

ACL主要分两种:标准ACL和扩展ACL。标准ACL只能基于源IP地址做过滤,扩展ACL则能基于源IP、目的IP、端口号、协议类型等多维度条件。

我记得有一次,客户要求只允许特定部门的员工访问财务系统,但其他流量不受影响。如果用标准ACL,只能拦源IP,拦不住目的端口。最后我用扩展ACL,指定了源网段、目的IP和TCP端口号,精准搞定。

ACL类型 编号范围 匹配条件 典型场景
标准ACL 1-99, 1300-1999 仅源IP地址 限制整个网段访问
扩展ACL 100-199, 2000-2699 源IP、目的IP、端口、协议 精细化访问控制
经验之谈:能用扩展ACL就别用标准ACL。标准ACL虽然简单,但控制粒度太粗,容易造成「误杀」或「漏放」。我见过太多因为标准ACL配置不当导致的网络故障了。

避坑指南:我踩过的那些坑

最后,分享几个我亲身经历过的ACL配置坑:

  • 隐式拒绝的坑——我曾经配完ACL后,发现所有流量都断了。检查了半天,才发现忘了加 permit ip any any。从那以后,我每次配ACL都会在末尾显式写一条允许或拒绝规则,避免被隐式规则坑到。
  • 顺序的坑——有一次我把精确规则放在了宽泛规则后面,结果精确规则永远不生效。排查时抓包发现流量被前面的宽泛规则匹配了。嗯,从那以后我养成了「先精确后宽泛」的习惯。
  • 方向的坑——入向和出向搞反了,导致该拦的没拦住,不该拦的反而被拦了。我的建议是:画一张数据流图,标清楚数据从哪进、从哪出,再决定ACL的方向。

ACL的工作原理其实不复杂,但细节决定成败。顺序、隐式拒绝、方向——这三个点你记住了,ACL这块基本就稳了。