
1. 为什么要用ACL没有访问控制的网络就像不设门禁的机房先讲一个我早年间带新人时常说的场景某公司内网里财务部服务器存放着全公司的薪资数据和报表。网络拓扑很简单所有部门在一个网段大家互相能通。某个实习生心血来潮在自己的工位上Ping了一下财务服务器的IP通了又随手试了一下445端口的共享文件夹结果真的弹出了文件列表。那一刻他有点慌了赶紧关掉窗口但这件事要是被别人用同样的方式做了呢网管根本不知道因为交换机不喊不叫默认放行一切流量。这就是ACL存在的根本理由在网络设备上定义一套规则告诉设备“哪些流量能过哪些流量必须丢”。思科官方对ACLAccess Control List的定义并不复杂——一系列允许或拒绝语句的集合但很多人学ACL时只学会了敲命令没学会怎么用它解决实际问题。本文就用Cisco Packet Tracer这个模拟器把标准访问控制列表从原理到配置、从踩坑到验证完整过一遍。看完之后你不仅能在一台路由器上写出能用的ACL还能明白什么时候该用标准ACL、什么时候该换扩展ACL、为什么规则顺序写错了会造成全网故障。学这篇内容适合哪些人正在备考CCNA的人上课听得懂但一碰设备就懵的在校生以及刚入职需要配置公司网络设备但不敢乱动生产环境的实习网工。Packet Tracer最大的价值就是让你随便折腾命令敲错了重启设备就能恢复这种试错成本在真实设备上是没有的。关于思科模拟器里的ACL实操市面上教程很多但大多数只告诉你“先access-list然后ip access-group”没有讲通配符掩码究竟在匹配什么、为什么标准ACL只能基于源地址、为什么ACL一定要在接口方向选对之后才生效。这些细节才是真正让人从“会敲命令”变成“会排错”的关键。下面直接从标准ACL的原理开始拆。2. 标准ACL的工作机制规则顺序、通配符掩码与隐含拒绝2.1 标准ACL到底匹配什么标准ACL编号范围1到99扩展编号1300到1999最核心的特征是只匹配源IP地址。它不关心你要去访问哪个服务器、用的是HTTP还是Telnet、源端口是几千还是几万——只要报文的源地址落在ACL规则指定的范围内这条规则就生效。这就是它和扩展ACL的本质区别。这个特性决定了标准ACL的使用位置尽量部署在靠近目标的那一侧。为什么举例来说公司有三个网段研发部192.168.10.0/24、市场部192.168.20.0/24、核心服务器区192.168.100.0/24。你希望禁止研发部访问服务器区的某些服务但又不影响市场部。如果ACL只匹配源地址那么把它放在研发部网关的出口和放在服务器区网关的入口效果会有很大差别放在研发部出口规则会影响研发部访问外面所有网段的流量放在服务器区网关入口规则只影响进入服务器区的流量。所以标准ACL不适合靠近源端部署否则容易误伤。这就是为什么你经常看到标准ACL被挂在离目标最近的接口上哪怕这样会让不需要经过该接口的流量白白穿越整个网络。这是一个典型的“用正确的位置弥补工具功能单一”的工程思路。2.2 通配符掩码不是子网掩码通配符掩码Wildcard Mask是ACL配置里最容易让人糊涂的概念。它和子网掩码写法长得像但规则完全相反子网掩码里1代表必须匹配0代表可以不匹配通配符掩码里0代表必须匹配1代表随意。翻译成人话通配符掩码中的0表示IP地址对应的那一位必须精确一样1表示这一位不用管0和1都能通过。主机192.168.1.1的通配符掩码0.0.0.0 等价写法host 192.168.1.1 整个192.168.1.0/24网段的通配符掩码0.0.0.255 等价写法192.168.1.0 0.0.0.255 所有IP地址的通配符掩码255.255.255.255 等价写法any计算方法是子网掩码按位取反。255.255.255.0取反就是0.0.0.255所以192.168.1.0 0.0.0.255就匹配192.168.1.0到192.168.1.255这个范围。这个规则不需要死记理解取反逻辑后自然就记住了。但是有几个不连续网段的场景会让人掉头发。比如要匹配192.168.1.0/24和192.168.3.0/24两个网段但不匹配192.168.2.0/24。用标准ACL的源地址匹配来做通配符掩码会变得很诡异。有些资料会给出192.168.1.0 0.0.2.255这种写法但实际工程中没人这么干——遇到不连续网段的需求首选方案是写多条ACL语句或者换用扩展ACL。标准ACL本身就不是为这种精细匹配设计的强行用通配符去凑不连续地址只会给自己留下排错隐患。2.3 隐含拒绝规则ACL的最后一句话ACL最坑人的特性在于它的结尾有一条看不见的规则deny any。也就是说配置ACL时只写了允许谁谁谁最后没写deny any系统也会自动把所有不在规则列表里的流量全部丢掉。很多人配置完ACL后网络不通排查了半天最后发现是因为只写了放行语句忘了还有一个隐含拒绝在悄悄工作。理解隐含拒绝需要先理解ACL的匹配顺序数据包到达接口后从ACL列表的第一行开始逐行比对一旦匹配到某条规则就立即执行该规则的允许或拒绝操作后面所有规则不再检查如果所有规则都不匹配最终落到隐含拒绝丢弃。比如说我定义了这样两条规则access-list 1 permit 192.168.10.0 0.0.0.255 access-list 1 deny 192.168.20.0 0.0.0.255实际效果是192.168.10.0/24的流量放行192.168.20.0/24的流量丢弃其他任何地址的流量同样丢弃。这个“其他任何地址”就是隐含拒绝。很多教程把ACL前三行写完就结束了真实配置中我会习惯性地在末尾显式写一条deny any或者deny ip any any。虽然不写系统也会执行同样的效果但显式写出来有两个好处一是排除ACL的人能一眼看到这条规则确实存在不会产生歧义二是后期修改ACL时向表里插入新规则时不会误以为列表就到此为止。2.4 入方向和出方向ACL生效的两个角度接口上的ACL有两个绑定方向。in方向处理的是从该接口接收进入设备的流量out方向处理的是从该接口发送出去的流量。这个方向选择如果搞错了ACL配置得再正确也不会产生预期效果。一个常见错误场景我在路由器Router0的Gig0/0接口上写了一个ACL打算阻止来自192.168.1.0/24网段的流量访问Router0后面的服务器。但我把ACL绑定到了Gig0/0的out方向而这个接口上出去的流量其实是从本路由器发往192.168.1.0/24网段的方向刚好反了流量照样畅通无阻。检查的时候一定要用show access-lists看计数器有没有增加——如果流量经过但没有命中规则命令不会报错但行为就是不对。这就是方向选错最典型的表现。3. 在Cisco Packet Tracer里从零配置标准ACL3.1 先搭一个能复现问题的拓扑纸上谈兵没有意义Packet Tracer的价值就在于把配置落到设备上。新建一个工作区拖入三台路由器、两台交换机、三台PC规划如下拓扑思路Router0作为总出口网关连接两个内部网段左侧PC0和PC1代表研发部IP地址为192.168.10.10和192.168.10.11属于192.168.10.0/24网段右侧PC2代表服务器区IP地址为192.168.100.10属于192.168.100.0/24网段Router0与左侧交换机相连的接口是Gig0/0IP为192.168.10.1与右侧交换机相连的接口是Gig0/1IP为192.168.100.1各PC的默认网关指向各自网段的路由器接口IP。这是最简单的一种拓扑但足够演示ACL的核心场景了。在配置ACL之前先确保全网能互相Ping通。这一步很多人会跳过结果ACL一挂上去网络不通了分不清是ACL的问题还是链路的问题。先把基础连通性验证清楚了再动ACL后面排查会轻松很多。3.2 写第一条标准ACL并绑定到接口现在需求来了允许PC0192.168.10.10访问服务器区的任何服务拒绝PC1192.168.10.11访问服务器区。注意是“拒绝访问服务器区”不是“拒绝所有流量”。按标准ACL的设计思路它只匹配源地址所以应该把ACL部署在靠近目标的Router0的Gig0/1接口上方向选择in。这样进入服务器区方向的流量才会被检查。在Router0上执行如下配置Routerenable Router#configure terminal Router(config)#access-list 1 permit host 192.168.10.10 Router(config)#interface gigabitEthernet 0/1 Router(config-if)#ip access-group 1 in Router(config-if)#end Router#write此时ACL 1只有一行permit主机192.168.10.10加上隐含拒绝实际效果就是只有来自192.168.10.10的流量能进入服务器区其他所有流量全部丢弃。PC1 Ping服务器区不通服务器区反Ping PC1也不通。如果你想验证这个配置确实生效去PC0上Ping服务器IP然后回到Router0上执行Router#show access-lists 1可以看到匹配计数在增长说明放行规则确实命中了。这就是ACL配置验证的基础操作比只在PC上按“Ping通了吗”要靠谱得多。3.3 多条规则的顺序先精确后宽泛继续延伸需求现在允许192.168.10.0/24整个网段访问服务器区但要单独拒绝其中一个用户192.168.10.50。很多初学者会这样写access-list 1 deny host 192.168.10.50 access-list 1 permit 192.168.10.0 0.0.0.255第一眼看上去没问题但ACL是逐行匹配的第一行deny host先比对只有源地址正好是192.168.10.50时才命中其他源地址继续向下匹配最终落到permit网段这行。这种顺序下deny和permit各自只作用于自己的范围看起来是对的。但如果把两条顺序调换一下access-list 1 permit 192.168.10.0 0.0.0.255 access-list 1 deny host 192.168.10.50问题就来了192.168.10.50这个主机地址也在192.168.10.0/24网段范围内数据包从第一行permit就已经被放行了后面的deny根本不会被检查到。这就是为什么配置ACL有一条铁律先写更精确的匹配规则再写宽泛的匹配规则。正确写法是把deny放前面。这并不难理解但实际排错时十次里有八次都是这种顺序问题。尤其在一个ACL列表持续增删改之后规则顺序很容易乱。Packet Tracer里可以在全局配置模式下用ip access-list standard 1进入命名式配置然后手动用编号插入规则比一条条敲access-list命令更可控。3.4 命名式标准ACL推荐给所有新手的写法上面用的是编号式标准ACL即access-list 1这种格式。还有一种写法是命名式标准ACL命令结构如下Router(config)#ip access-list standard BLOCK_RND Router(config-std-nacl)#permit host 192.168.10.10 Router(config-std-nacl)#deny 192.168.10.0 0.0.0.255 Router(config-std-nacl)#exit Router(config)#interface gigabitEthernet 0/1 Router(config-if)#ip access-group BLOCK_RND in命名式ACL的最大优势是名称一眼能看出用途。一个名为BLOCK_RND的ACL比一个名为5的ACL在半年之后更容易回忆起来。生产环境里我倾向于给每一个ACL起一个可读性强的名字比如ALLOW_MGMT_ONLY、BLOCK_VENDOR_SUBNET。Packet Tracer对这种命名式ACL支持得很好而且完全可以在命名式ACL里同时写permit和deny语句。有一个细节需要留意命名式ACL里规则是有默认序号的比如10、20、30如果想在现有规则中间插入新规则需要指定新的序号或者用no 10删除现有规则再重新添加。Packet Tracer的界面操作也可以编辑这些序号但命令行方式更直观也更接近真实设备操作习惯。4. 标准ACL实战中最容易踩的坑我踩过的和你们即将踩的4.1 只写permit忘了隐含拒绝导致路由器与服务器彻底失联这是我排障生涯中遇到频率最高的一个“低级错误”但它造成的后果一点都不低级。场景回放某台路由器上有一个标准ACL管理员只想放行192.168.1.0/24访问后面的一台服务器于是写了一条access-list 10 permit 192.168.1.0 0.0.0.255然后把它绑到了服务器的网关接口的in方向。结果不仅是其他网段访问不了服务器连路由器自己管理用的Telnet、SSH也一并断了。原因就是隐含拒绝把设备的控制面流量也拦住了。很多教材会强调ACL影响数据面的转发流量但不要忽略控制面流量同样会经过接口ACL检查。管理地址如果不在放行清单里远程管理会话就会被ACL无情拒绝。这就是为什么在很多老网工的规范配置里ACL列表的最后会加上一条permit host 管理站IP并且一定放在deny之前虽然隐含拒绝必然兜底但显式放行管理IP能防止因为调整其他规则顺序导致自己把自己锁在门外。处理方法是要么在ACL里放行管理IP要么把管理接口和业务接口分开。生产环境中更建议后者——带外管理或者专用管理VLAN。Packet Tracer的模拟环境没有那么高要求但习惯要从实验阶段养成等真到了生产环境再去改习惯代价就太大了。4.2 通配符掩码把网段和主机搞混再举一个通配符掩码的典型错误有人想匹配192.168.1.0到192.168.1.255的整个网段写成了192.168.1.0 0.0.0.0。从命令角度说这并不报错它匹配的只是192.168.1.0这一个主机地址实际网络里根本没这个主机在发流量。ACL一绑定接口看起来好像有效果但又好像没效果——因为其他主机照样能访问目标只有真正的192.168.1.0地址几乎不会作为源地址出现才会被匹配。这种问题特别坑因为命令毫无报错show run也看不出逻辑问题只能靠show access-lists里的计数器观察命中情况。这个坑的规避方法其实很简单写ACL之前先在草稿纸上把要匹配的网段、子网掩码、通配符掩码三个值列出来取反计算一遍再敲进设备。宁可在这一步多花两分钟也不要等ACL上线后在半夜被电话叫醒。4.3 标准ACL绑错方向服务不可达但命令不报错接前面方向问题的例子展开说一个更隐蔽的情况。假设网络拓扑是三层结构核心路由器连接两个楼层二楼有一个服务器群三楼是办公区。我接到需求“不让三楼的某个网段访问二楼服务器”然后在核心路由器连接二楼服务器的接口上写了一个ACL绑定out方向里面的规则是deny三楼的源地址。但实际上二楼服务器接口的out方向流量是核心路由器发往二楼服务器的源地址是核心路由器自己的接口地址根本不会匹配三楼源地址。于是ACL就像一道设错了位置的门禁卡机器完全没起到作用。方向结合标准ACL的特性有一个简单的判断方法站在接口的角度问自己——我想拦的是从这个接口进来的流量还是从这个接口出去的流量如果是“进入服务器区的流量”那就在服务器区接口的in方向拦如果是“从路由器发往某个网段的流量”那才考虑out方向。刚开始做实验的时候每次绑定前都把这个逻辑过一遍比事后排错效率高得多。4.4 远程管理会话被ACL锁死恢复手段必须留一手现实中远程维护设备时误绑ACL导致自己和设备断连是非常经典的“自锁”事故。原因五花八门ACL里忘了放行自己的管理IP、ACL顺序调整后自己掉到deny规则后面、接口方向选错然后一不小心把管理流量也拦了。Packet Tracer里遇到这种情况还好可以直接重启设备或关掉电源再开模拟器的“重新加载”功能相当于物理重启。但真实生产环境这么做代价极高可能造成业务中断。所以我的建议是两条第一实验阶段就养成习惯任何ACL绑定到接口之前先用show access-lists确认管理IP在放行规则里、且放行规则在匹配顺序上不会被前面的deny抢了先第二登录设备时保留一个备用入口——比如串口console或者带外管理网络。真被锁了至少还能稳住心态去恢复配置。这也是为什么我在给团队培训时反复强调ACL是一个把双刃剑它限制别人的同时如果不小心也会限制你自己。5. 验证ACL是否生效计数器、调试与常见排错链路5.1 show命令族把ACL的内部状态翻出来看配置完ACL一定不要急着宣布“搞定”。必须验证、验证、再验证。思科设备上最常用的三条验证命令Router#show access-lists Router#show ip access-lists Router#show ip interface gigabitEthernet 0/1show access-lists会显示每条规则被匹配的次数。当你在PC上发起Ping或访问流量时对应规则后面的计数会增加。如果流量确实在走这个接口而一个规则始终是0次命中说明这个规则可能没被触发原因可能是方向错了、通配符掩码写错了、或者是ACL根本就没被绑定到接口上。这条命令几乎可以定位ACL配置问题80%的原因。show ip interface则能看到接口上具体绑定了哪个方向的哪个ACL用于确认配置确实下发到了接口上。有些时候ACL在全局配置里写好了但忘了绑定到接口流量自然就不会受控。5.2 用扩展Ping和抓包确认流量走向如果show命令显示ACL有命中但业务依然不通就需要用更底层的手段验证。在Packet Tracer里有一个非常好用的工具右下角的模拟模式Simulation Mode。激活之后数据包逐跳传输每一步都能看到设备的处理动作包括ACL是允许还是拒绝。这对于学习ACL来说简直是外挂级功能强烈建议初学的同学一定要亲手在模拟模式下发一个Ping包观察它经过路由器的接口时ACL的匹配路径。模拟模式看的是图形化流程真实生产环境没有这种条件。退一步的做法是使用扩展Ping指定源地址测试不同网段的连通性。比如在PC1上执行Ping源是PC1的IP目标服务器IP看到超时再到PC0上执行相同目标的Ping通了。这种对比就能确定ACL确实只拦了PC1。扩展Ping的用法是进入特权模式后直接敲ping然后按提示填写源接口或源地址、目标地址、重复次数等参数。5.3 完整排错链路从“Ping不通”到“ACL计数异常”整理一个排错思路供参考按照这个链路走大部分ACL问题都能在十分钟内定位确认物理链路和IP配置没问题接口up/up网关正确。在不绑ACL的情况下确认直连网段的连通性正常。绑定ACL后再测一遍确认确实是从“通”变成了“不通”锁定是ACL引起的。用show ip interface确认ACL绑定方向和接口无误。用show access-lists查看计数是否增长。计数增长说明ACL匹配到了流量接下来逐个排除规则顺序及匹配逻辑计数不增长大概率方向或接口绑错了。用Packet Tracer模拟模式逐跳观察定位具体哪一条规则允许或拒绝了数据包。修正ACL规则、保存配置再验证。这套链路看起来很简单但实际排错中很多人会跳过第1步直接在ACL上反复试最后发现根本是网段划分错了或者接口忘了配IP。据我观察至少三成“ACL问题”最终发现根本与ACL无关。6. 从标准ACL走向扩展ACL什么时候应换方案6.1 标准ACL的选型边界标准ACL简单、执行效率高、占用设备CPU资源少但它的局限性也很明显只匹配源地址。很多实际需求并不是“不让某个网段的所有流量进来”而是“不让某个网段访问我的Web服务但允许它访问我的数据库端口”。这种需求标准ACL完全无能为力。举一个明确的场景公司里有一个数据服务器研发部需要访问它上面的MySQL服务TCP 3306但不需要访问它的HTTP服务TCP 80。如果用标准ACL你在靠近数据服务器的接口上只能控制源地址无法区分端口。服务器为了业务需要同时开着80和3306结果研发部既能访问MySQL也能访问Web页面。这时候就需要扩展ACL。扩展ACL的编号范围是100到199扩展编号2000到2699它可以同时匹配源地址、目标地址、协议类型、源端口、目标端口等多个维度配置语法也更长Router(config)#access-list 100 permit tcp host 192.168.10.10 host 192.168.100.10 eq 3306 Router(config)#access-list 100 deny ip any any Router(config)#interface gigabitEthernet 0/1 Router(config-if)#ip access-group 100 in这条规则的效果是只允许192.168.10.10访问192.168.100.10上的TCP 3306端口其余所有流量全部丢弃。6.2 标准ACL的典型应用场景这不是说标准ACL可以被淘汰事实上它在一些场景下依然是最合适的方案基于来源网段的访问隔离比如禁止某个办公区网段访问服务器区不区分具体服务。这种情况下标准ACL一条permit或deny就解决问题没必要上扩展ACL增加配置复杂度。用于路由过滤OSPF、RIP等动态路由协议做路由信息过滤时标准ACL是常用的匹配工具。其他命令中引用ACL做身份识别比如NAT、route-map里可以用ACL作为匹配工具标准ACL的简单性在这里反而成了优点。理解这个边界之后就能明白为什么网络工程师招聘要求里总是同时出现“标准ACL”和“扩展ACL”——它们像螺丝刀和扳手一样各有各的适用场景不存在谁完全替代谁。7. 一段来自排障一线的经验补充最后讲一个我从Packet Tracer一路学到真实设备上一直适用的心得。每次配完ACL我习惯性地做三件事第一write或者copy running-config startup-config保存配置。模拟器关机后配置可能丢失生产设备意外断电后如果没有保存所有ACL策略都会回到上一次保存的状态这种事故我听说过不止一次。第二把ACL的规则逐条读一遍特别关注deny和permit的顺序。有的设备上会自动生成“序号”查看时一目了然有的则显示配置顺序逐个核对是否符合预期先精确后宽泛、管理放行在前、隐含拒绝永远是兜底。第三在模拟器里特意制造一次“破坏性测试”。比如故意把一个放行的规则删掉确认设备会拒绝预期流量再重新加回去。这听起来多此一举但这种对“什么时候会断、什么时候会通”的敏感度恰恰是排错能力最核心的部分。ACL的配置命令就那几条但能把ACL用得收放自如靠的就是对规则匹配顺序和方向选择的反复体感训练。如果你现在还在Packet Tracer阶段建议把文中的拓扑、配置命令和排错链路亲手敲一遍不要复制粘贴。等你自己敲通了第一条ACL再回头来看这些注意事项你会发现它们全都变成了肌肉记忆的一部分。