1. ACL到底是干什么的:从一个真实场景说起
做网络设备的同学对ACL这个缩写应该都不陌生,全称是Access Control List,翻译过来叫访问控制列表。名字听着挺官方,实际做的事情很朴素:在设备上写一系列“允许”或“拒绝”的规则,让设备按照这些规则决定数据包是放行还是丢弃。
我在华为ensp里做实验时,最爱举的例子是公司网络隔离。假设你是某公司网管,老板提了个需求:财务部那台服务器(IP是192.168.10.10)只允许财务部员工访问,研发部和访客WiFi都不能碰。如果没有ACL,那这台服务器在网络里就是“裸奔”的——只要路由可达,谁都能访问。而配置了ACL之后,你在路由器或防火墙上定好规则:源地址属于192.168.10.0/24网段的放行,其他地址一律拒绝。这就是ACL最典型的应用:流量筛子。
ACL在ensp里的实用价值远不止“拦几个包”这么简单。往小了说,它可以限制某个IP访问某个端口,比如只允许特定主机远程管理交换机;往大了说,它是企业网络做安全策略、带宽控制、NAT地址转换的基础组件。很多同学在HCIA、HCIP备考时都会遇到ACL,但考试只是让你“会配命令”,实际工作中你还要知道为什么这么配、遇到流量放行不了时怎么排查。这篇文章就围绕ensp环境,把这套东西从头到尾捋一遍。
2. 方案选型与核心概念:基本ACL和高级ACL该怎么选
2.1 基本ACL和高级ACL的本质区别
华为设备上,ACL按编号范围和应用场景可以分成三种:基本ACL(编号2000~2999)、高级ACL(编号3000~3999)、二层ACL(编号4000~4999)。ensp里最常用的是前两种。
基本ACL只匹配源IP地址,最多再加个分片标记和时间段。它适合做“粗粒度”的过滤:按网段拦,按主机拦,简单粗暴。比如前面说的“财务部服务器只允许财务网段访问”,用基本ACL就够了——我只要看包从哪里来,根本不关心它要去哪个端口。
高级ACL就复杂多了,能匹配源IP、目的IP、协议类型(TCP/UDP/ICMP等)、源端口、目的端口、TCP标志位等。它可以做到“细粒度”控制:比如“拒绝研发部主机访问财务服务器的3389端口,但允许它访问80端口”——这种规则基本ACL做不了,必须上高级ACL。
选型的核心逻辑就一句话:看你的控制粒度需求。如果只需要按源地址拉黑或放行一个IP段,用基本ACL省事也省资源;如果涉及“什么服务能访问什么服务”这种端口级控制,必须用高级ACL。华为设备里有不少同学喜欢图省事,不管三七二十一全用高级ACL,其实没必要。基本ACL在硬件芯片上匹配效率更高,规则也更清晰易读。
2.2 通配符掩码:ACL匹配IP段的关键
配置ACL时最劝退新手的就是通配符掩码(wildcard mask)。比如你要匹配192.168.1.0这个网段的所有主机,语法是:
rule 5 permit source 192.168.1.0 0.0.0.255这里的0.0.0.255就是通配符掩码。它的匹配逻辑和子网掩码相反:子网掩码里1表示必须匹配,0表示无所谓;通配符掩码里0表示必须精确匹配,1表示这一位可以任意。所以0.0.0.255的含义就是前24位必须跟192.168.1一模一样,最后8位随便填,匹配的就是192.168.1.0/24这个网段的所有地址。
这里有个很多教程没讲透的坑:通配符掩码和反掩码看起来一样,但使用场景完全不同。ACL里用的是通配符掩码,它的作用是“位匹配”,而不是告诉你这个网段的网络号或广播地址。有的同学在OSPF配置里宣告网段时也用反掩码,比如network 192.168.1.0 0.0.0.255,看到两边写的都是0.0.0.255,就以为是一回事。其实两者的计算方式相同,但OSPF那边是在定义路由发布的网络范围,ACL这边是在定义包匹配的地址范围,混用容易导致配置结果跟预想不一致。
个别情况会遇到非常规的通配符掩码,比如0.0.0.254这种“不规则”掩码。它匹配的是192.168.1.1、192.168.1.3、192.168.1.5……这些奇数结尾的IP,因为最后一位被忽略,倒数第二位必须为0。这种写法在做奇偶校验匹配时有用,但实际工程中很少用,知道有这回事即可,别在常规配置里硬凑。
2.3 rule编号规则的潜规则
华为ACL里每条规则都有一个rule编号,默认是5的倍数递增,也可以手动指定。为什么要留间隔?因为ACL规则按编号从小到大顺序匹配,一旦某条规则命中,后面的规则就不再看了。你如果编号用1、2、3连排,以后想往中间插一条规则,只能删掉后面所有规则再重做。用5的倍数就是给未来的新增规则留出插入空间。
还有个细节:如果两条rule编号相同,后配置的那条会覆盖先配置的。所以我在企业设备上调ACL时,习惯先display acl检查已有规则的编号,避免不小心覆盖掉重要条目。ensp里虽然报错提示比真机友好些,但养成这个习惯能少踩很多坑。
3. ensp实操:经典ACL配置全过程
3.1 实验拓扑与IP规划
我们在ensp里搭一个最小化但完整的场景。准备一台路由器(型号随便,我用的是AR2220)、一台交换机(S5700)、三台PC。PC1模拟财务部主机,IP设为192.168.10.10/24,接在交换机的GigabitEthernet0/0/1口;PC2模拟研发部主机,IP设为192.168.20.20/24,接在交换机GigabitEthernet0/0/2口。路由器两个接口分别接交换机的两个VLAN接口,或者为了简单起见,直接把PC1所在网段和PC2所在网段分别配置在路由器的两个物理接口上。
更贴近企业实际的拓扑是:交换机上划分VLAN10对应财务部网段、VLAN20对应研发部网段,通过trunk口上联路由器,路由器用子接口或vlanif终结VLAN。这种做法配置量大了些,但对练ACL倒是没影响,因为ACL过滤发生在三层设备上,跟二层VLAN划分不影响ACL本身逻辑。为了把重点放在ACL上,我用一个简化版:
- 路由器G0/0/0:192.168.10.1/24,接交换机VLAN10
- 路由器G0/0/1:192.168.20.1/24,接交换机VLAN20
- PC1(财务):192.168.10.10/24,网关192.168.10.1
- PC2(研发):192.168.20.20/24,网关192.168.20.1
需求:只允许PC1(财务)访问路由器某接口,禁止PC2(研发)访问。
其实这个实验有个更直接的需求化场景:公司要求研发部不能登录路由器进行远程管理,而财务部可以。那就在VTY(远程登录虚拟终端)接口下调用ACL,只放行192.168.10.10这台主机。这个场景比“两台PC互ping”更贴近真实网络管理需求,而且能顺便练到ACL在VTY下的调用方式。
3.2 基本ACL配置步骤:从定义到调用
第一步,在路由器上创建基本ACL。用编号2000。命令如下:
system-view acl number 2000 rule 5 permit source 192.168.10.10 0.0.0.0 rule 10 deny source 192.168.20.0 0.0.0.255第一条规则精确匹配PC1的IP,通配符掩码填0.0.0.0,四个0表示所有位都必须精确匹配,效果等同于“只认这一台机器”。第二条规则拒绝整个研发部网段。因为ACL默认的规则匹配顺序是从小到大,所以PC1会先命中rule 5并放行,PC2会匹配到rule 10被拒绝。
但这里有个关键点:ACL本身只是一张规则表,它不会自动生效。你必须把它绑定到某个接口的某个方向上,它才真正产生作用。在接口下调用ACL的语法:
interface GigabitEthernet0/0/1 traffic-filter inbound acl 2000这个命令把ACL 2000应用在G0/0/1接口的入方向。也就是说,从PC侧进入路由器的流量会先过一遍ACL规则,再走路由转发。inbound和outbound这两个方向词是新手犯错的重灾区:inbound指流量进入该接口的方向,outbound指流量从该接口出去的方向。
拿我们的场景来说,PC1访问路由器时流量从G0/0/1进入,所以必须在G0/0/1的inbound方向调用ACL。如果在outbound方向调用,ACL也能起作用,但逻辑上绕了一个弯:数据包先进来,在路由查询之后准备从其他接口出去时才被过滤。这两种写法在最终效果上可能一致,但排查问题时方向不同,日志里的统计位置也不一样,理解原理比死记命令更重要。
配置完建议执行display acl 2000查看规则命中计数。如果PC2访问被ACL拦掉了,命中计数就会增加,这是验证配置是否生效的最直观手段。
3.3 高级ACL配置与VTY远程管理限制
接下来升级场景:公司里有三台管理主机,分别是192.168.10.10、192.168.10.11、192.168.30.30,老板说只允许前两台能telnet到路由器,第三台禁止。这个需求如果只用基本ACL,就得建一个匹配“一个IP或另一个IP”的规则。基本ACL的源地址匹配项不能写多个地址,只能单条规则匹配一个地址或一个网段。如果想匹配多个互不相邻的IP,更好的选择是用高级ACL,虽然高级ACL通常用于端口级控制,但它的源地址匹配逻辑也一样。
其实更专业的做法是写两条rule,都permit分别匹配两台IP,然后最后deny all。不在高级ACL上硬凑。但在ensp里,练习高级ACL最经典的需求是“限制特定端口”或“限制telnet服务”。
acl number 3000 rule 5 permit tcp source 192.168.10.10 0.0.0.0 destination 192.168.10.1 0.0.0.0 destination-port eq 23 rule 10 deny tcp source 192.168.30.30 0.0.0.0 destination 192.168.10.1 0.0.0.0 destination-port eq 23 rule 15 deny ip这里注意,规则15的deny ip是隐式拒绝规则的显式版本。华为ACL在规则列表末尾默认有一条“拒绝所有”的隐含规则,也就是说,即使你不写rule 15,任何没被前面规则匹配到的流量最终都会被拒绝。把隐式规则显式写出来有助于阅读和理解,但在实际配置中如果前面规则已经覆盖了所有场景,不写也没问题。
在VTY接口下调用3000号ACL:
user-interface vty 0 4 acl 3000 inbound这样telnet到设备的管理流量就会被ACL过滤。注意VTY下调用ACL用的命令是acl而不是traffic-filter,别搞混了。接口下调用用traffic-filter,VTY下调用直接跟acl。
VTY下调用ACL有个方向细节:inbound方向是用户主动发起telnet连接进入设备的方向。你如果想限制的是“设备telnet到别的地方”这种出方向流量,那就要在outbound方向调用。真实运维中限制网管终端Telnet设备是最常见的需求,所以90%的情况都是配inbound。
3.4 在ensp上验证实验结果
配置完成后,在PC上测试连通性。ensp的PC终端自带有命令行工具,可以直接在PC上打开终端,输入ping命令测试:
- 从PC1(192.168.10.10)ping路由器接口192.168.10.1:能通,因为ACL 2000的rule 5放行了它。
- 从PC2(192.168.20.20)ping路由器接口192.168.20.1:这里要注意,PC2的地址是192.168.20.20,它的流量从路由器的G0/0/1接口进来,但ACL 2000调用的是G0/0/1的inbound方向吗?我前面把ACL绑在G0/0/1的inbound上,而PC2的数据进入路由器走的是G0/0/1,所以会被拦。如果ACL绑反了、绑到G0/0/0上,那就拦不到PC2。
测试telnet时,可以在PC终端直接执行telnet 192.168.10.1,看能不能出登录界面。被ACL挡掉时会一直卡在连接阶段或者直接提示超时,命中计数在路由器上会快速增加。这个过程就是标准的ACL“配、调、验”三步走。
4. 接口流量方向选择与实战排错
4.1 为什么接口方向决定ACL成败
接口方向是ACL配置里最容易出错的地方,单独拿出来重点讲。华为设备里,traffic-filter命令绑定的inbound和outbound,是站在“该接口”的角度看的。
- inbound:数据包从外部进入该接口的方向。
- outbound:数据包从该接口向外发送的方向。
这个看似简单的概念,在复杂的多接口拓扑里很容易绕晕。比如在三层交换机上,PC在VLAN10里,服务器在VLAN20里,你想过滤“PC访问服务器”的流量,可以绑在VLANIF10的inbound方向,也可以绑在VLANIF20的outbound方向。两种绑法效果几乎一样,但侧重点不同:绑在源侧接口inbound,可以理解为“从源头掐断”;绑在目的侧接口outbound,相当于“在门口把守”。实战中我习惯绑在inbound方向,因为能在流量进入设备的第一个环节就拦截,减少设备内部的无效处理。
如果涉及多台路由器串联,比如PC经过路由器A再到路由器B再到服务器,ACL绑在哪台设备上,会导致“流量在哪个节点被丢弃”完全不同。抓包排错时,你首先要确认ACL绑定的接口和方向是否和流量路径一致。我见过不少案例,ACL规则配得完全正确,最后发现是接口方向理解反了,流量压根没经过这个接口。在ensp里如果你用了类似wireshark抓包的功能,可以很容易看到报文是否到达这个接口,从而判断方向配置有没有问题。
4.2 ACL规则的匹配顺序和隐式拒绝
华为ACL默认的匹配顺序是config模式,即按照rule编号从小到大匹配,一旦匹配就不再往下看。还有一种是auto模式,设备自动把更具体的规则排在前面,ensp默认使用config模式,考试和企业配置也基本都用config模式。
因为“匹配即停止”这个机制,规则的先后顺序就变得极其重要。举个我遇到过很多次的错误示范:
acl number 3000 rule 5 deny ip source 192.168.10.0 0.0.0.255 rule 10 permit tcp source 192.168.10.50 0.0.0.0 destination-port eq 80配置者的本意是“整个192.168.10.0/24网段都不允许上网,但192.168.10.50这台机器可以访问80端口”。因为rule 5先执行,192.168.10.50也在网段内,直接就被deny了,rule 10永远不会被匹配到。正确写法是先把特例放前面,再写网段范围的拒绝规则:
rule 5 permit tcp source 192.168.10.50 0.0.0.0 destination-port eq 80 rule 10 deny ip source 192.168.10.0 0.0.0.255这个例子很好地诠释了ACL配置的核心原则:特例在前,范围在后。这比背任何命令都重要。
华为ACL的隐式拒绝规则值得再强调一次:如果一条流量没有匹配到任何显式规则,它最终会被拒绝。这个设计让ACL天生就是“默认拒绝所有”的安全策略。有些同学配置ACL后测试不通,第一反应是“我的规则哪儿写错了”,其实可能是流量正好落进了隐式拒绝的兜底里。如果你希望某个网段“默认放行”,必须在规则末尾显式写一条permit。当然,显式permit all会让ACL失去安全性,所以在企业环境里一般不这么干,而是把精细化规则写全。
4.3 实战排错常用的display命令
ensp和华为真机的排错命令高度一致,这里把最常用的几条整理出来。
查看ACL配置和命中计数:
display acl all这条命令会显示所有ACL的编号、规则内容和命中次数。如果Counter列有数字在增长,说明有流量命中了对应规则。
查看接口下的ACL绑定情况:
display traffic-filter applied-record它会列出每个接口上绑定的ACL及方向。
查看全局是否启用了ACL及其统计信息:
display acl running查看VTY下调用ACL的情况:
display acl 3000 display user-interface排错思路通常是这样的:先确认配置正确性,再确认方向正确性,再看命中计数。如果ACL规则和方向都正确,但命中计数始终为0,说明流量压根没到这里,问题在路由或链路层。如果命中计数在增长,但业务还是不通,那可能是规则顺序或规则内容的问题,比如deny规则覆盖了允许规则。
还有一点:ensp里如果路由器接口或PC配置有误导致ARP不通,ACL的拦截效果会被底层的二层通信故障掩盖。我在给学员做演示时经常强调,先确认基础连通性,再排查ACL。基础不通的链路,ACL再精确也没意义。
4.4 Time-range配合ACL做分时段控制
ACL还有个进阶玩法:配合time-range做基于时间的访问控制。比如规定“工作日的9点到18点禁止访问视频网站”,其他时间放行。
先定义时间段:
time-range work-time 09:00 to 18:00 working-day然后在ACL规则中引用它:
acl number 3000 rule 5 deny tcp destination-port eq 80 time-range work-time rule 10 permit ip这个配置在ensp里也能模拟出来。企业里做“下班后禁止访问办公系统”“周末禁止生产环境操作”这类需求时,time-range非常实用。
注意ensp的time-range语法和真机略有差异,比如有的版本支持working-day关键字,有的版本写法不同,需要确认当前ensp版本。如果设备不支持,也可以手动把时间写全,写成periodic的工作日范围语句,具体语法以设备的问号提示为准。
5. 常见错误与避坑指南
5.1 忘写规则编号导致覆盖
这是我在ensp群里看到提问最多的问题。某学员第一次配ACL:
acl 2000 rule permit source 192.168.1.0 0.0.0.255 rule deny source 192.168.2.0 0.0.0.255两条rule都没有写编号,系统自动分配,但关键问题在于第二条命令执行后,它和第一条如果都自动分到了相同的编号(都从5开始),那第二条会覆盖第一条。华为设备在未指定编号时会自动生成编号,两次配置若间距相同,后配置的规则会继续递增还是覆盖,取决于设备的实现方式。但为了避免歧义和不可控,强烈建议每条rule都显式指定编号。如果你希望往现有ACL里追加规则,先display acl 2000看下最新编号,然后从下一个编号继续写。
5.2 误绑方向:最常见的“没效果”假象
ACL匹配的是经过设备接口的数据流,绑错方向在ensp里不会像真机那样报错,但流量就是不受控制。验证方法是:先ping通目标,再把ACL绑定方向改一下,看行为有没有变化。这个对比测试能帮你快速定位方向是否绑反。
还有一种情况是设备上有多个接口路径,比如PC到服务器要经过RouterA的G0/0/0进、G0/0/1出,你把ACL绑在RouterB的某个接口上,那根本没用,因为流量根本不经过RouterB。ACL绑定必须落在真实的流量路径上,这是很多人忽略的一个大前提。
5.3 通配符掩码计算错误
比如要匹配192.168.1.128/25这个网段,很多同学会惯性写出0.0.0.255。实际上/25的网段有128个地址,通配符掩码应该是0.0.0.127。写错的结果是ACL匹配范围比预期大了一倍,可能连192.168.1.0/25的地址也一起匹配了。计算通配符掩码的方法是用255.255.255.255减去子网掩码,比如255.255.255.128相减得到127.255.255.255,但要注意这个结果只是数值上的反掩码,ACL中0.0.0.127才是正确匹配128个地址的通配符。
实际上更稳妥的方式是不要从子网掩码换算,而是直接用二进制去推:需要精确匹配的位填0,可变的位填1。手算了几个例子之后就很快了。
5.4 忘记ACL默认拒绝的行为
很多新人在ensp里配好ACL后,发现所有设备都无法互访了,一看配置:只写了permit规则和deny规则,没写deny all,但流量怎么就被拒了?原因就是华为ACL的默认隐含规则是拒绝所有未匹配流量,而且这条隐含规则在display acl输出里看不到。这不是Bug,是设计如此。如果你希望一个ACL只拦特定的几类流量、其他都放行,必须写一条显式的permit ip规则放在最后。
有人问“为什么我在ACL里只写了一条permit规则,其他所有流量都通不了,而我在Cisco设备上同样配置却通?”这就是厂商差异。华为ACL默认拒绝,思科某些场景下ACL只过滤匹配的流量、未匹配的放行,机制不同。不要拿一套思维套两家设备。
5.5 在ensp中telnet测试被忽略的AR/交换机差异
ensp模拟器里,路由器和交换机对ACL的支持程度有细微差别。大多数情况下三者都能用基本/高级ACL,但在VTY下调用ACL时,部分交换机型号或版本对directions的支持不同。如果遇到命令无法识别,可以先确认当前设备型号和ensp版本,或者使用undo命令重配。
另外,ensp模拟器的VTY默认可能不允许telnet登录,需要先配VTY密码和认证方式:
user-interface vty 0 4 authentication-mode password set authentication password cipher 123456 protocol inbound telnet如果ACL配置里没有先放行telnet流量,VTY登录会直接失败,容易让人误以为是ACL的问题。很多学员就是在这一步卡了很久:ACL配了、VTY也调用了,但从PC上telnet路由器就是不成功,其实是VTY本身没启动telnet服务。排错时一定要先把基础服务调通,再叠加ACL验证。
6. 我的一些经验之谈
ACL在ensp里练熟之后,换到真机上基本无缝对接,因为ensp对华为命令的模拟已经做得相当到位了。但这恰恰也带来了一个隐患:ensp里ACL配错了只是实验环境里出问题,而真机上一条ACL绑错方向或者放行范围过大,是可能造成生产业务中断的。
我在实际项目里做ACL变更,奉行一个“三步原则”:先备份当前配置,再在变更窗口内操作,最后用对比命令验证前后状态。在ensp里做实验时也应该养成这个习惯,因为你在实验环境里形成的操作习惯,会直接影响你在真实设备上的行为模式。很多面试官问ACL相关知识,不仅看你会不会配规则,更看你会不会安全地改规则、会不会快速回退。在ensp里提前练好这些“软技能”,对职业发展帮助很大。
ACL只是网络访问控制的一个基础模块,它解决的是“通或不通”的问题。更进一步,还有基于状态的防火墙策略、基于用户的准入控制、微分段等更细致的手段。但不管多高级的方案,底层都离不开“源地址、目的地址、端口、协议”这几个匹配要素,而这正是ACL的核心。把ACL吃透,等于把网络访问控制的地基打牢。
一个小技巧收尾:在ensp里做完ACL实验后,我习惯用display acl all看一遍所有规则的Counter,如果一条规则命中了预期之外的流量,马上用undo rule把这条规则删掉重新设计。规则命中计数是ACL排错的“第一现场”,养成查看它的习惯,你会比那些只盯着配置看的同学快得多。