PPP 的 CHAP 认证是网络实验里一个特别容易被"配通了但说不清"的知识点。很多人在模拟器里敲完几条命令,看到接口 up、ping 通了就收工,可一旦被问到"三次握手到底握了什么""为什么密码不能明文传""为什么我两边都配了还是认证失败",就答不上来。这篇内容围绕华为 eNSP 环境下的 PPP CHAP 认证展开,把原理、配置命令、验证方法和实际踩坑经验一次讲透。适合正在备考网络方向认证、做实验课作业,或者刚接触广域网链路配置的朋友——不管你是第一次听说 CHAP,还是配过但总在细节上翻车,都能从里面找到能直接抄作业的部分。
CHAP 全称 Challenge Handshake Authentication Protocol,中文叫挑战握手认证协议,是 PPP 链路层里用来验证对端身份的一套机制。它和 PAP 最大的区别在于:PAP 是把用户名密码明文发过去让对方核对,而 CHAP 全程不传密码本身,只传摘要值。这个差异决定了 CHAP 在安全性上明显更胜一筹,也是它在现网广域网链路里更常见的原因。下面我按"为什么这么设计—怎么配—怎么验证—怎么排错"的顺序,把这块内容拆开讲。
1. 先搞清楚 CHAP 到底在防什么
要理解 CHAP,得先明白 PPP 链路建立时到底发生了什么。PPP 不是一上来就能传数据的,它有一套分层的协商流程,从下往上依次是链路控制协议 LCP、认证协议(PAP 或 CHAP)、网络控制协议 NCP。CHAP 就处在中间这一层,它的职责很单纯:在链路真正承载业务数据之前,确认对面这个设备是不是"自己人"。
1.1 PPP 的三层协商顺序决定了 CHAP 的位置
PPP 的链路建立过程可以类比成进小区:LCP 阶段相当于在门口确认双方用什么语言交流、要不要查证件(协商认证方式);认证阶段就是真的掏证件核对身份;NCP 阶段才是进了楼、分配门牌号(协商 IP 地址等网络层参数)。这个顺序是硬性的,认证没过,NCP 根本不会启动,链路也就无法承载 IP 流量。
具体到报文层面,LCP 协商时会通过 Configure-Request 报文里的 Authentication-Protocol 选项告诉对端"我要求用 CHAP 认证"。如果两端配置的认证方式不一致——比如一端要求 CHAP、另一端只支持 PAP,或者一端要求认证、另一端压根没配认证——LCP 协商就会失败,接口状态会卡在某个中间态。这是实际排错时第一个要看的地方,很多人只盯着 CHAP 的密码,却忽略了 LCP 阶段就已经谈崩了。
我见过不少初学者把 CHAP 当成一个独立功能去配,配完发现不生效,其实问题出在 LCP 协商阶段。所以记住一句话:CHAP 是 LCP 协商出来的结果,不是凭空开启的开关。你在接口上敲ppp authentication-mode chap,本质是在 LCP 的 Configure-Request 里带上"我要 CHAP"这个诉求,对端得能接住这个诉求,协商才能往下走。
1.2 CHAP 的三次握手到底交换了什么
CHAP 的认证过程是三次报文交互,我把它拆成"挑战—响应—确认"三步:
- 挑战(Challenge):认证方(Authenticator)生成一个随机数,连同自己的主机名和一个报文 ID,打包成 Challenge 报文发给被认证方。这个随机数每次认证都不一样,这是 CHAP 能防重放攻击的关键。
- 响应(Response):被认证方收到挑战后,用报文 ID、随机数、自己的密码,一起丢进 MD5 算法算出一个摘要值,然后把"用户名 + 这个摘要值"发回去。注意,密码本身从头到尾没有出现在链路上。
- 确认(Success/Failure):认证方自己手里也有这个用户的密码,它用同样的报文 ID、同样的随机数、同样的密码算一遍 MD5,两个摘要一比对,一致就回 Success,不一致就回 Failure。
这里有个细节值得多说一句:认证方怎么知道该用哪个密码去算?它是根据 Response 报文里带的用户名,去本地 AAA 配置里查对应的密码。所以被认证方发过去的用户名,必须在认证方的本地用户表里存在,且密码一致,这是 CHAP 认证成功的两个必要条件,缺一不可。很多人配了密码但忘了建本地用户,或者用户名大小写对不上,都会导致认证失败。
1.3 为什么 CHAP 比 PAP 更值得用
PAP 的流程简单粗暴:被认证方直接把用户名密码明文发过去,认证方核对。问题在于,链路上任何能抓包的位置都能看到密码原文,安全性约等于零。CHAP 用 MD5 摘要替代明文,即使有人抓到 Response 报文,拿到的也只是一串哈希值,无法反推出密码。
更关键的是 CHAP 的随机数机制。每次认证的 Challenge 都带一个新的随机数,同样的密码每次算出来的摘要都不同,攻击者即使录下了一次完整的认证过程,也没法重放——因为下次的随机数变了,旧的摘要对不上。这个设计思路和很多现代认证协议是一致的,理解了这一点,你就明白为什么 CHAP 的密码配置必须两端严格一致,因为任何一方算错一个字节,摘要就对不上。
不过也要客观说一句,CHAP 用的 MD5 在今天看来强度已经不算高,但在链路层认证这个场景下,它防的是链路窃听和重放,不是对抗强算力破解,所以仍然是够用且广泛部署的方案。做实验时理解它的设计逻辑,比死记命令更有价值。
2. eNSP 里把 CHAP 跑起来的最小配置
理论讲完,进入动手环节。我在 eNSP 里搭 CHAP 实验,习惯用两台路由器通过 Serial 接口直连,这是最干净的环境,排除了交换机、VLAN 等干扰因素。下面这套配置是我反复验证过的,照着敲基本不会出问题,但每一步为什么这么配,我会讲清楚。
2.1 实验拓扑与基础准备
拓扑很简单:两台路由器 R1、R2,各用一个 Serial 接口对接。eNSP 里选路由器时,Serial 接口需要设备支持,一般选 AR 系列模拟得比较顺手。连线时注意选 Serial 线,别选成 Ethernet 线,否则接口根本起不来。
基础配置包括给接口配 IP 地址、保证物理层和协议层 up。这里有个 eNSP 特有的坑:Serial 接口的时钟频率。在真实设备上,DCE 端需要配 clock,eNSP 里如果两端都没配时钟,接口可能一直是 down 状态。我的习惯是在其中一端(模拟 DCE)的接口下敲clock rate 64000,另一端不用配。这个细节很多教程一笔带过,但新手卡在这里半天找不到原因的情况太常见了。
IP 地址规划上,我用 10.1.1.0/24 这个网段,R1 的 Serial 接口配 10.1.1.1/24,R2 配 10.1.1.2/24。配完先别急着上 CHAP,先确认接口能 up、能 ping 通——虽然此时还没配认证,但基础连通性先验证一遍,后面出问题才好定位是认证的锅还是链路本身的锅。
2.2 认证方与被认证方的角色划分
CHAP 是单向认证还是双向认证,取决于你的需求。单向认证就是一方验证另一方,双向认证是双方互相验证。实验里我建议先做单向,把流程跑通,再加双向,循序渐进。
假设 R1 是认证方,R2 是被认证方。那么:
- R1 上要配:接口启用 CHAP 认证(
ppp authentication-mode chap),并建一个本地用户,用户名是 R2 发过来的名字,密码是双方约定的密码。 - R2 上要配:接口把发送的用户名和密码告诉 PPP(
ppp chap user和ppp chap password)。
这里最容易搞混的是"谁建用户"。记住原则:认证方建用户,被认证方配发送的用户名密码。因为认证方要拿本地用户表去核对对方发来的身份,而被认证方只需要证明"我是谁"。
2.3 认证方 R1 的完整命令
先看 R1 的配置。进入系统视图后,先建本地用户:
system-view aaa local-user r2 password cipher Huawei@123 local-user r2 service-type ppp quit这两条local-user命令是关键。第一条建用户并设密码,cipher表示密码以密文形式存储(敲命令时输入的是明文,保存后显示为密文)。第二条service-type ppp指定这个用户可用于 PPP 认证——这一步极容易漏,漏了的话用户建了也白建,认证照样失败,因为服务类型不匹配。
然后进接口配认证模式:
interface Serial1/0/0 link-protocol ppp ppp authentication-mode chap quitlink-protocol ppp在 Serial 接口上通常是默认的,但显式敲一遍更稳妥,避免某些设备默认是 HDLC 导致后面全乱。ppp authentication-mode chap就是告诉接口"用 CHAP 验证对端"。
2.4 被认证方 R2 的完整命令
R2 这边不建用户,只配发送的身份信息:
system-view interface Serial1/0/0 link-protocol ppp ppp chap user r2 ppp chap password cipher Huawei@123 quitppp chap user r2里的r2必须和 R1 上建的用户名完全一致,大小写敏感。ppp chap password必须和 R1 上设的密码完全一致。这两条对上了,认证才能过。
配完两端,用display interface Serial1/0/0看接口状态,正常情况下 Physical 和 Protocol 都应该是 up。如果 Protocol 一直是 down,八成是认证没过,往下看排错部分。
2.5 双向认证怎么加
单向跑通后,加双向认证就是对称操作:R2 也要建本地用户(用户名是 R1 发过来的名字),R1 也要配ppp chap user和ppp chap password。具体来说:
R2 上加:
aaa local-user r1 password cipher Huawei@456 local-user r1 service-type ppp quit interface Serial1/0/0 ppp authentication-mode chapR1 上加:
interface Serial1/0/0 ppp chap user r1 ppp chap password cipher Huawei@456注意双向认证时两端的密码可以不同(R1 验证 R2 用一个密码,R2 验证 R1 用另一个密码),只要每一对"认证方本地用户密码"和"被认证方发送密码"各自对上即可。这个细节很多人以为必须两端密码一样,其实不必,理解了三次握手的逻辑就明白为什么。
3. 认证到底过没过,看这几个地方
配完不等于通了,验证环节才是把知识变成能力的关键。我习惯从"接口状态—认证报文—调试信息"三个层次去看,由粗到细,定位问题效率最高。
3.1 接口状态是第一道信号
display interface Serial1/0/0是最快的判断手段。重点看两个字段:current state 和 Line protocol current state。前者反映物理层,后者反映协议层。物理层 up 但协议层 down,基本可以锁定是 LCP 或认证阶段的问题。
如果协议层 down,再敲display ppp interface Serial1/0/0看 PPP 的详细状态,能看到 LCP 是否 open、认证是否成功。这个命令比单纯的 interface 命令信息更细,是排查 PPP 问题的常用入口。
3.2 用调试命令看三次握手过程
想看 CHAP 报文交互的细节,用调试命令最直接:
terminal monitor terminal debugging debugging ppp chap all敲完这几条,如果链路正在认证,屏幕上会滚出 Challenge、Response、Success 的报文信息。看到 Success 就说明认证过了;看到 Failure 或者压根没有 Response,就往密码、用户名、服务类型这几个方向查。
提示:调试信息输出量大,实验环境用完记得
undo debugging all关掉,否则可能刷屏影响其他操作,在真实设备上更要谨慎使用。
3.3 一个容易被忽略的验证点:本地用户的服务类型
前面提过service-type ppp不能漏,这里再强调一次验证方法。用display local-user能看到本地用户的详细信息,重点确认 service-type 里包含 ppp。如果只看到别的服务类型,说明建用户时漏了这条,补上即可。这个点之所以值得单独说,是因为它不报错、不提示,纯粹是"配了但不生效",排查时特别费时间。
4. 认证失败的排查链路,我按这个顺序走
CHAP 认证失败是实验里最高频的问题,我总结了一套固定的排查顺序,从最外层往最里层查,基本能在几分钟内定位。这套顺序的价值在于避免东一榔头西一棒子地乱试。
4.1 第一步:确认 LCP 协商有没有过
认证失败先别急着看密码,先确认 LCP 阶段是否正常。如果两端认证模式配置不一致(一端 chap 一端 pap,或者一端要求认证一端没配),LCP 就过不了,根本轮不到 CHAP 出场。用display ppp interface看 LCP 状态,或者开debugging ppp lcp all看协商报文。这一步排除掉,才能确定问题真的在 CHAP 层。
4.2 第二步:核对用户名、密码、服务类型三件套
LCP 没问题,就查认证三要素:
| 检查项 | 认证方(R1) | 被认证方(R2) | 常见错误 |
|---|---|---|---|
| 用户名 | 本地用户名为 r2 | ppp chap user r2 | 大小写不一致、拼写错误 |
| 密码 | 本地用户密码 Huawei@123 | ppp chap password同值 | 多空格、特殊字符转义问题 |
| 服务类型 | service-type ppp | 无需配置 | 认证方漏配导致不生效 |
这张表我建议做实验时对着逐项打勾。实际踩坑最多的就是用户名大小写和密码里的特殊字符——比如密码里带@或#,在某些输入环境下可能被特殊处理,导致实际存进去的密码和你以为的不一样。
4.3 第三步:看调试信息里的具体报错
前两步都排除了,就开debugging ppp chap all看报文。常见现象有两种:一是认证方发了 Challenge 但收不到 Response,通常是被认证方没配ppp chap user/password,或者接口没启用 PPP;二是收到了 Response 但回 Failure,那就是密码或用户名对不上,回到第二步细查。
还有一种隐蔽情况:被认证方发了 Response,但认证方本地压根没有这个用户,也会回 Failure。这时候调试信息里能看到认证方在查用户表失败,提示很明确,照着补用户就行。
4.4 第四步:排除 eNSP 环境本身的干扰
如果配置反复检查都没问题,就要怀疑模拟器环境了。eNSP 里常见的问题包括:设备启动不完整导致配置没生效、Serial 接口时钟没配导致物理层不稳、保存的配置和运行配置不一致。我的习惯是display current-configuration看运行配置,确认敲进去的命令真的生效了,而不是停留在启动配置里。必要时重启设备重新加载,比在错误状态上反复折腾更快。
5. 几个只有实际配过才会懂的经验
命令和流程之外,有些经验是文档里不会写、只有动手配过才体会得到的。这部分我挑几个最有代表性的分享。
5.1 密码用 cipher 还是 simple,别想当然
配置本地用户和ppp chap password时,都有 cipher 和 simple 两种选项。cipher 表示存储时加密,simple 表示明文存储。实验环境图省事用 simple 也能跑通,但我建议养成用 cipher 的习惯——一方面贴近真实运维的安全要求,另一方面能提前踩到"密文显示和明文输入不一致"的坑,理解设备是怎么处理密码的。用 cipher 时,display current-configuration看到的是密文,这是正常的,不代表配错了。
5.2 单向认证和双向认证的密码可以不同
前面提过这点,这里再展开一下。双向认证时,R1 验证 R2 用的密码(存在 R1 本地用户表里)和 R2 验证 R1 用的密码(存在 R2 本地用户表里)是两个独立的密码,完全可以不一样。很多人误以为双向认证必须两端密码相同,于是配了个一样的,虽然也能通,但没理解背后的逻辑。想清楚"每次认证是认证方拿自己的用户表去核对对方发来的摘要"这一点,就明白两个方向是独立的认证过程。
5.3 调试信息要看,但别一直开着
debugging ppp chap all是排查利器,但它输出的是实时报文,链路一有风吹草动就刷屏。实验时我通常只在需要观察认证过程的那几秒打开,看完立刻undo debugging all。在真实设备上更要克制,调试信息占用 CPU 资源,生产环境长时间开着可能影响设备性能。这个习惯从实验阶段就养成,比事后纠正强。
5.4 接口协议 down 先怀疑认证,别急着换线
新手遇到接口协议层 down,第一反应常是"线是不是接错了""模拟器是不是坏了",然后反复重连、重启。其实 PPP 场景下协议层 down 绝大多数是 LCP 或认证没过,先按第 4 节的排查链路走一遍,比盲目换线高效得多。物理层 down 才去查线缆和时钟,协议层 down 就往协商和认证方向查,这个判断逻辑能省下大量无效折腾。
6. 把 CHAP 放进更大的知识框架里
单独看 CHAP,它只是 PPP 的一个认证选项;但把它放进整个链路层协商的框架里,很多设计就串起来了。LCP 负责谈条件,认证负责验身份,NCP 负责配网络参数,三者层层递进,任何一层没过,链路就停在那一层。理解了这条主线,再去看 PPP 的其他特性——比如多链路捆绑、回拨——都能找到它们各自在这条主线上的位置。
我在实际配置中体会最深的一点是:CHAP 的难点不在命令,而在对"谁认证谁、谁存密码、谁发身份"这套角色关系的理解。命令就那么几条,背下来不难,但角色搞反了,配多少遍都不通。所以每次带新人做这个实验,我都先让他们把三次握手的报文流向画一遍,画对了再动手敲命令,成功率明显提高。这个顺序反过来——先敲命令再补原理——往往就是配通了也说不清,换个拓扑又不会了。
另外,CHAP 的随机数机制和摘要比对思路,在很多上层认证协议里都能看到影子。把这个链路层的例子吃透,后面接触更复杂的认证体系时,会发现自己理解得快很多,因为底层那套"挑战—响应—比对"的骨架是相通的。做实验时多问一句"为什么这么设计",比多敲十遍命令更有长期价值。