事情得从一次加班说起。那年出口路由器上挂着三十多条老ACL(Access Control List,访问控制列表),每条规则还没有注释。业务部门报某个系统访问不通,没人敢动那堆规则,因为谁也不清楚哪条是当年临时加的、哪条已经失效。我蹲在机房里一条一条捋,最后发现只是新加的一条deny规则顺序不对,把后面所有permit全挡住了。从那次之后我就坚定了一件事:ACL这种东西,命令不过是几分钟的事,真正考验人的是对匹配逻辑、通配符掩码和接口方向的理解。这篇文章不打算按教科书的路子讲,我就按华为、H3C设备上的实际配置经验,把基本ACL、高级ACL、IPv6 ACL配置实验、ACL配合策略路由这些高频场景一次说透,再把我踩过的坑和排查思路全摆出来。适合刚进数通圈子的新人,也适合已经会敲命令但经常被“明明配置了却不生效”折磨的老兵。
1. 先打通概念:ACL到底是干什么的
1.1 一个我常用的比喻:小区门禁卡
理解ACL最简单的方式,就是把它想象成小区门口保安手里的登记表。普通门禁卡只能核对你是不是本小区的人,对应的就是基本ACL,只看源地址,匹配“你是谁”,决定放不放行。高级一点的门禁系统会登记你的姓名、要去哪栋楼、什么时间来、是否携带电脑设备,对应高级ACL,它可以检查源地址、目的地址、协议类型、源端口、目的端口,甚至TCP标志位。
所以ACL在网络设备里的本质是一张“包过滤规则表”。当数据包从接口进来或者出去时,设备把报文里的关键字段提取出来,从上到下和这张表里的规则逐条比对,命中哪条就执行哪条的动作,也就是permit放行或者deny丢弃。它是一个非常底层的流分类工具,也是后面要讲的策略路由、QoS队列、防火墙策略的基础。理解了这一点,你就明白为什么ACL配置不当会影响整个业务链路。
1.2 按编号分档:基本、高级、二层ACL怎么选
华为和H3C设备的ACL编号区间划分几乎是通用的,设计这个编号段的逻辑本身就暗示了用途。基本ACL用2000到2999,匹配维度最少,通常只匹配源IP地址,偶尔加时间范围。优点是占用设备资源少、规则简单清晰,适合做网段级别的粗粒度隔离。高级ACL用3000到3999,能匹配五元组,也就是源IP、目的IP、协议号、源端口、目的端口,还能匹配TCP标志位、DSCP优先级、分片标记等,是生产环境里的主力。
二层ACL用4000到4999,匹配源MAC、目的MAC、VLAN ID、二层协议类型,一般用在接入交换机上,用来防止仿冒MAC、限制某个终端的接入权限。用户自定义ACL是5000到5999,通常用于配合QoS策略做复杂流分类,普通运维用得少。
| ACL类型 | 编号范围 | 主要匹配维度 | 典型场景 |
|---|---|---|---|
| 基本ACL | 2000-2999 | 源IP地址、时间范围 | 限制网段互访、限制远程管理IP |
| 高级ACL | 3000-3999 | 源/目的IP、协议、端口、标志位 | 服务器端口保护、业务精细化放行 |
| 二层ACL | 4000-4999 | 源/目的MAC、VLAN、二层协议 | 接入层终端管控、防MAC仿冒 |
选型时的经验是:能用基本ACL解决的事不要升级到高级ACL,规则越复杂,排查越费劲。但涉及服务器端口管控、业务白名单,直接用高级ACL,别拿基本ACL硬凑。对了,如果你见过Cisco设备,它的标准ACL编号是1到99、扩展ACL是100到199,本质功能一样,但编号逻辑不同,换厂商时别记混。
2. 配置ACL前必须吃透的四个关键点
2.1 规则匹配顺序和隐式拒绝:90%的ACL故障都出在这里
ACL的匹配逻辑非常简单,但“简单”恰恰是问题源头。设备从上到下逐条匹配规则,一旦命中就立刻执行动作,不再继续往下看。这意味着规则顺序直接决定最终效果。比如你想拒绝192.168.1.0网段,却在最前面写了一条permit any,那所有流量都会命中permit any后直接放行,后面的deny规则根本轮不到执行。
另一个容易被忽略的是隐式拒绝。所有ACL末尾都有一条看不见的规则:deny any。如果流量把每条规则都过了一遍仍然没有匹配项,最终会被丢弃。所以有些新手写ACL时只写了deny规则,忘了放行必要的流量,结果全网断连。
我的习惯是在动手配置前先用表格列一个“业务访问矩阵”:谁访问谁、走哪个协议端口、方向是什么、是允许还是拒绝。把规则顺序按“具体放前面、宽泛放后面”的原则排好,再翻译成命令行。这样在设备上敲命令只是最后一步,而不是边敲边想。
2.2 通配符掩码别当子网掩码用:30秒学会计算
这是ACL配置里翻车率最高的知识点。ACL里的掩码叫通配符掩码,和路由配置里的子网掩码完全不是一回事。通配符掩码里的0表示“必须严格匹配这一位”,1表示“这一位可以任意忽略”。
举个例子,192.168.1.0 0.0.0.255表示前三段必须匹配192.168.1,最后一段任意,所以匹配的是192.168.1.0到192.168.1.255整个网段。如果写192.168.1.10 0.0.0.0,四个字节全部严格匹配,那就是精确匹配这单个IP,更简洁的写法是host 192.168.1.10。如果写any,等价于0.0.0.0 255.255.255.255,也就是全部匹配。
计算通配符掩码有个傻瓜式方法:直接用255.255.255.255减去子网掩码。比如/22的子网掩码是255.255.252.0,那通配符掩码就是0.0.3.255。这比对着二进制一个个抠快得多,也不容易错。
2.3 规则编号步长:为什么建议从5开始
华为和H3C设备配置ACL时,如果不写规则编号,系统会自动编号,默认步长是5,也就是5、10、15、20这样递增。这个设计是给后续插入规则留预留空间的。比如你现在有rule 5和rule 10,之后想在中间插一条,就可以直接指定rule 7或者rule 6,不需要重排后面的规则。
如果不用步长而连续写了很多条不带编号的规则,后续想插入一条新规则时只能把后面所有规则都删了重写,这在生产设备上非常危险。所以我建议平时养成手动指定编号的习惯,每个ACL开头留几条空编号,特别是允许类规则之间要留出足够间隔。查看已有规则编号用display acl,删除中间某条规则用undo rule rule-id,这个操作不会影响其他规则。
2.4 接口方向inbound/outbound,到底怎么理解
ACL最终要挂在接口上才生效,命令是traffic-filter inbound acl xxx或traffic-filter outbound acl xxx。判断方向时站在设备内部去看:流量从外部进入这个接口,叫inbound;流量从这个接口发出去,叫outbound。
最容易混淆的场景是保护服务器。服务器连着接入交换机的端口,客户端流量是从外部进入这个端口再到服务器,所以在该接口上应该配置inbound方向。如果错误地配置成outbound,ACL根本匹配不到这些流量。还有一个细节:ACL过滤是单向的,允许客户端访问服务器的同时,服务器返回客户端的流量不会受这条规则影响。如果业务上需要限制服务器主动外连,必须在出方向单独配置另一条规则。判断方向时不要把“流入业务”和“入接口方向”混在一起,一定要在纸上画出设备和流量的相对关系。
3. 实操案例:华为/H3C设备上的ACL配置全过程
3.1 案例一:基本ACL限制指定网段访问管理接口
先来一个最常用的场景。公司要求只有网管段的10.10.1.0/24地址能SSH登录交换机,其他地址一律禁止。这个需求用基本ACL就能满足,因为在SSH登录场景里只关心来源IP。
acl number 2001 rule 5 permit source 10.10.1.0 0.0.0.255配置完ACL之后,把它应用到VTY虚拟终端线上。H3C设备命令:
user-interface vty 0 4 acl 2001 inbound authentication-mode aaa华为设备的配置思路一样,VTY视图下同样执行acl 2001 inbound。这里的inbound指的是远程登录进入系统方向,很好理解。需要特别提醒的是,ACL末尾隐式拒绝所有,如果允许列表里漏掉了某个网管地址,操作到一半就可能把自己锁在设备外面。所以第一次部署时先把所有允许的管理IP全部写进规则里,再三确认没问题再应用。配置完成后不要关当前SSH窗口,另开一个窗口从不同地址测试登录是否被拒绝。
3.2 案例二:高级ACL精确放行Web和SSH流量
服务器10.0.0.10上跑着Web服务,办公网192.168.1.0/24的客户端需要访问80和443端口,同时运维人员要从办公网SSH登录这台服务器的22端口,其他来源和端口一律拒绝。这是典型的高级ACL五元组匹配场景。
acl number 3000 rule 5 permit tcp source 192.168.1.0 0.0.0.255 destination 10.0.0.10 0.0.0.0 destination-port eq 80 rule 10 permit tcp source 192.168.1.0 0.0.0.255 destination 10.0.0.10 0.0.0.0 destination-port eq 443 rule 15 permit tcp source 192.168.1.0 0.0.0.255 destination 10.0.0.10 0.0.0.0 destination-port eq 22 rule 20 deny ip在连接服务器的接口视图下应用:
interface GigabitEthernet0/0/1 traffic-filter inbound acl 3000解释一下这里的逻辑。destination 10.0.0.10 0.0.0.0就是精确匹配目的IP 10.0.0.10;destination-port eq 80表示目的端口等于80。最后一条deny ip其实可以省略,因为隐式拒绝会兜底,但我习惯加上,理由是可以附带日志功能。需要加日志时写成rule 20 deny ip logging,这样丢包还能在设备上留下审计记录。不过要注意,生产环境大量访问被拒绝时,日志放大效应会消耗CPU,建议只在短时排障期开启。
3.3 案例三:华三设备IPv6 ACL配置实验
IPv6环境下的ACL配置和IPv4有几点不同。首先是进入ACL视图的命令变成acl ipv6,其次是在规则里地址后面跟的是前缀长度,而不是通配符掩码。比如要允许2001:db8:1::/64网段访问2001:db8:2::10这台IPv6服务器的80端口,配置如下。
acl ipv6 number 3000 rule 5 permit tcp source 2001:db8:1:: 64 destination 2001:db8:2::10 128 destination-port eq 80H3C和华为新版VRP系统的命令格式基本一致。这里的64表示源地址的前缀长度,等价于IPv4通配符掩码0.0.0.255的作用;128表示精确匹配单个IPv6地址。很多人在IPv6 ACL上栽跟头,就是把IPv4的写法套过来,想在地址后面写一串通配符掩码,结果语法报错。IPv6 ACL的规则参数就是前缀长度,这是和IPv4最大的区别。
接口下的应用命令也要带上ipv6关键字:
interface GigabitEthernet1/0/1 traffic-filter inbound ipv6 acl 3000实验时我的操作流程是先在设备上配置好IPv6地址和路由,确认两端能ping通,再下发ACL规则。这样做的好处是ACL生效前网络是通的,一旦ACL应用后ping不通,就能立刻确认是ACL拦截。如果反过来先把ACL配上再调路由,出现问题时就分不清是路由问题还是ACL问题,排查效率低很多。
3.4 案例四:ACL匹配配合策略路由,把特定流量引到指定下一跳
ACL本身只做匹配和动作,动作只有permit和deny。但ACL还可以作为其他功能的“识别工具”,最常见的就是配合策略路由实现分流。比如分公司192.168.2.0/24访问总部业务网段172.16.10.0/24时,希望强制走专线下一跳10.0.0.2,其他流量走默认路由。
acl number 3002 rule 5 permit ip source 192.168.2.0 0.0.0.255 destination 172.16.10.0 0.0.0.255然后配置策略路由,调用这个ACL:
policy-based-route PBR_A permit node 10 if-match acl 3002 apply next-hop 10.0.0.2最后在流量的入接口上应用策略路由:
interface GigabitEthernet0/0/0 ip policy-based-route PBR_A理解一下这个过程:ACL负责“认出”哪些流量需要特殊处理,策略路由负责“执行”把流量扔到指定下一跳。两者是分离的。如果ACL没有命中,策略路由就不生效;如果ACL命中了但下一跳不可达,行为取决于设备版本,有些会放弃策略路由,退回按普通路由表转发,有些则直接丢弃。所以上线后务必抓包验证,不能只盯着配置本身。
4. 常见问题与排查技巧实录
4.1 现象:ACL配了,流量还是“正常”进出
这是被问得最多的一个问题:“规则明明写上去了,怎么访问还是通的?”遇到这种情况,先别怀疑设备坏了,按顺序排查。第一步确认ACL到底挂到哪个接口、哪个方向了,在设备上执行display traffic-filter applied-record,把当前接口下的ACL应用情况全部列出来看。第二步要弄清楚业务流量的进出方向,画出流量路径,对照接口方向判断inbound和outbound有没有选反。
第三步看规则本身。display acl 3000会显示出每条规则的匹配计数,这个信息极有价值。如果命中计数一直为零,说明规则本身没匹配到流量,重点检查通配符掩码和端口号是否写错。如果计数很大但业务还是通,再往顺序和放行规则上想。第四步,临时把规则里的deny改成permit做对照测试,验证ACL是否是唯一变量,这个方法虽然简单粗暴,但非常有效。
4.2 通配符掩码翻车现场:源地址怎么变成单个IP了
之前说过一个真实的坑:有同事想把192.168.1.0/24这个网段加入白名单,配置命令写成了rule 5 permit source 192.168.1.0 255.255.255.0。这条命令不会报错,设备正常接受,但通配符掩码255.255.255.0的含义是匹配“192.168.1.0”这个单一IP地址的最后一个字节必须为0,前面三个字节反而无所谓。所以实际匹配范围根本不是192.168.1.0/24,而基本是只有192.168.1.0这一个地址,几乎没有任何真实流量会命中。
这种错误最坑的地方在于它不报错,不细心根本发现不了。所以配置完ACL后必须用display acl复查一遍,看规则的匹配结果是否和预期一致。我的习惯是直接在草稿纸上先算一遍通配符掩码,凡是要匹配一个网段,就写成诸如0.0.0.255、0.0.3.255这种以255结尾的形式;凡是精确匹配,就写0.0.0.0或者用host关键字。只要通配符掩码里出现了255在中间或开头,就停一下,想清楚再说。
4.3 用display命令让规则“开口说话”
调试ACL离不开几个命令,我列一个现场常用速查表。
| 目的 | H3C/华为命令 | 说明 |
|---|---|---|
| 查看ACL规则与命中次数 | display acl 3000 | 最常用,优先看匹配计数 |
| 查看接口ACL应用情况 | display traffic-filter applied-record | 查方向和接口挂载 |
| 清空ACL统计计数 | reset acl counter 3000 | 调整后重新统计验证 |
| 查看所有ACL规则 | display acl all | 变更前检查编号冲突 |
| 查看策略路由 | display ip policy-based-route | 策略路由场景下配合使用 |
有个经验分享一下:调整ACL后先执行reset acl counter把计数清零,再发起测试流量,过几秒重新display acl,看目标规则的计数是否增长。如果增长,说明ACL参与了处理;如果不增长,先别纠结配置,重点检查流量是不是根本就没走到这个接口上来。这种“让数据说话”的排查方式,比对着配置发呆有效率得多。
4.4 变更演练:如何在生产环境安全上线ACL
ACL变更虽然日常,但出问题就是全网断连级别的故障。我给自己定了一套流程,分享给同行参考。第一,变更前把当前配置完整导出,至少导出接口配置和ACL配置,关键业务服务商的网段端口清单也整理好,避免上线时才发现漏放行。第二,先在测试设备上或者用一台空闲接口演练一遍,把命令敲熟,确认语法在当前设备版本下完全兼容。第三,预演回退方案。接口下去掉ACL就是一行undo traffic-filter inbound,但对一个复杂的ACL做修改时,回退脚本最好提前准备好。
第四点也是最容易被忽视的:设备远程管理通道千万不要被自己的变更波及。如果ACL是用在VTY下的登录限制,那配置前必须确保console口可用,或者有带外管理通道。否则一旦ACL写错,当前SSH连接被断,你就只能打车去机房了。这个教训我不是一次听到,是真有人被锁在设备外面过。最后,上线时间选在业务低峰,变更后保留观察窗口,至少观察十分钟再离场。
我个人操作ACL时养成的习惯不算多复杂,但很管用。每一条规则后面都加上description描述,写清楚这条规则是谁、在什么时候、为了什么业务加的;同时用一张Excel表格维护“业务网段、端口、规则编号、负责人”的映射关系。定期把设备上的ACL导出来对一遍,把命中计数低到可疑的规则单独标出来,找业务确认后再清理。设备上的ACL规则不是越全越好,规则越多,后续维护成本越高,出错概率也越大。最后再分享一个保命技巧:做任何可能影响管理通道的ACL变更之前,确保console线已经接好,或者带外管理开着。这个习惯是从一次远程配置失误之后养成的,那次如果没留后路,我可能就要半夜赶去机房刷机了。