宽带拨号失败时日志里反复出现“PAP authentication failed”估计不少人都被这一行字折磨过。PPPoE这个协议天天在路由器里跑但真正把它拆开看明白的机会并不多。这次我在华为eNSP里把PPPoE Server和PPPoE Client完整搭了一遍从AAA认证、Virtual-Template接入、Dialer拨号、地址池下发到抓包观察PADI/PADO/PADR/PADS整套流程都跑通了。这篇文章适合刚接触华为路由设备、准备考证或者想在模拟环境里验证PPPoE工作原理的同学。照着拓扑和配置就能复现但我更希望大家关注的不是命令本身而是每个接口和参数为什么这么设计。1. 实验之前的三个关键认知1.1 PPoE协议到底在做什么PPPoE的全称是Point-to-Point Protocol over Ethernet它的核心任务是把PPP帧封装在以太网帧里传输。以太网天生是共享介质、多点接入的网络谁都能往链路上发数据没有认证、没有计费、也没有给用户动态分配地址的机制。而PPP协议正好补齐了这些能力它能协商链路参数、做认证PAP/CHAP、动态分配IP地址。PPPoE就是把两者拼接在一起。实际拨号过程分成两个阶段。发现阶段Discovery Stage用以太网类型0x8863的报文完成PADI、PADO、PADR、PADS四次握手相当于在共享链路上找到对端并建立一条“虚拟点对点链路”同时给会话分配一个Session ID。会话阶段PPP Session Stage用以太网类型0x8864承载PPP报文继续做LCP协商、认证和IPCP地址下发。可以用一个生活化的比喻来理解以太网像是一间嘈杂的大教室你不知道隔了几排的那个人是不是你要找的人PPPoE先通过发现阶段确认彼此身份建立起一条“专属电话线”之后所有通信都在这条专属信道上完成。还有一个必须记住的数字因为每个以太网帧里要额外塞进PPPoE头和PPP头一共8字节所以PPPoE链路的用户数据MTU从1500降到1492。后面排查大包不通、网页卡顿等问题根源经常就在这个8字节上。1.2 为什么用eNSP做这个实验eNSP是华为官方提供的网络模拟工具和真实VRP命令高度一致用来做PPPoE实验有几点明显优势。第一零硬件成本不需要找两台真路由器、一根串口线或者运营商级接入设备第二拓扑搭建非常快从拖设备到连线不到五分钟第三eNSP支持在链路上直接启动抓包分析发现阶段和PPP协商过程非常方便。第四配置可以保存中途搞坏了随时Reset重来不用像真机那样担心配置救不回来。当然模拟器也有它的限制某些高级特性支持不完整不同版本对PPPoE的支持程度也有差异。我在实验里专门选了AR2220这台设备兼容性和稳定性都比较理想。如果你手头模板里只有AR201或者更老的型号优先换AR2220能少踩很多莫名其妙的坑。1.3 拓扑设计与地址规划整个实验的拓扑非常简单只有两台路由器和两台PC。PPPoE-Client路由器的G0/0/0接口连接PPPoE-Server路由器的G0/0/0接口模拟用户侧到运营商接入侧之间的链路Client的G0/0/1接口连接PC1模拟用户家庭内网Server的G0/0/1接口连接PC2模拟运营商侧的一台业务服务器。网络划分为三段各司其职区域网段说明用户内网192.168.10.0/24PC1所在的内网网关是Client的G0/0/1拨号地址段192.168.100.0/24PPPoE会话建立后Server分配地址给Client的Dialer接口运营商内网192.168.200.0/24PC2所在网段网关是Server的G0/0/1PC1和PC2都是静态IP不需要额外配置DHCP。拨号账号这里固定用test密码用简单密码123。认证方式先用PAP跑通全流程因为PAP的报文明文可见非常适合抓包学习跑通之后再把认证方式改成CHAP对比一下会理解得更透。1.4 配置之前的一个习惯动手之前建议先把两台设备的重启完成。eNSP里AR2220启动需要一点时间全部设备亮起并稳定后再操作。不要在设备还在加载的时候就敲命令否则会出现命令敲进去了配置却丢了一部分的现象。我自己的习惯是先改设备名验证设备可操作再进入正题。设备名分别改成PPPoE-Server和PPPoE-Client后续看日志和抓包会清楚很多。2. 服务端配置从虚拟接口说起2.1 为什么服务端需要一个Virtual-Template很多第一次做PPPoE实验的人都会在Server上找物理接口该怎么配IP结果发现无论怎么配都有点别扭。原因是PPPoE Server不是像普通三层接口那样收数据而是在物理接口上监听PPPoE发现报文等客户端拨上来后动态生成临时的虚拟接入接口。这个动态生成的过程不能凭空发生必须有一个“模板”来规定生成出来的接口长什么样、用哪些参数这个模板就是Virtual-Template。Virtual-Template可以理解成一个空白合同模板每一个拨号用户上来系统就按这个模板复印一份生成Virtual-Access接口为用户提供独立的三层接入通道。因此在Server端关键是配置Virtual-Template1而不是在G0/0/0上堆IP地址。2.2 配置AAA本地认证用户先在Server上创建用于拨号认证的本地用户。输入以下命令sysname PPPoE-Server aaa local-user test password cipher 123 local-user test service-type pppservice-type ppp这行很关键它限定这个本地用户只用于PPP/PPPoE接入不能用来登录设备。实验环境里这样最安全也最贴近生产环境的要求。很多人习惯把用户建出来就不管service-type结果后续登录出现各种权限问题根源就在授权类型上。如果后面想改成CHAP认证服务端的用户配置不用动只是把认证方式从PAP换成CHAP即可。这一点稍后会讲。2.3 创建地址池和Virtual-Template接口接着配置IP地址池这个地址池专门用于给拨号客户端下发地址ip pool pppoe_pool network 192.168.100.0 mask 255.255.255.0 gateway-list 192.168.100.1 excluded-ip-address 192.168.100.1地址池的网段和Virtual-Template接口必须保持同一个网段否则客户端拿到地址后无法把网关和自身地址落在同一网段照样不通。gateway-list填写的是Virtual-Template接口的地址也就是客户端拿到的默认网关。excluded-ip-address把这台Server自身占用的地址排除掉虽然VT接口本身也会使用这个地址但显式排除能避免地址池和接口地址冲突这是一个稳妥的做法。接着配置Virtual-Template1interface Virtual-Template1 ip address 192.168.100.1 255.255.255.0 ppp authentication-mode pap remote address pool pppoe_poolremote address pool pppoe_pool这一行是地址下发的核心。它的含义是当客户端通过IPCP请求地址时从名为pppoe_pool的地址池中分配一个空闲地址给客户端。如果漏掉这一行客户端拨号会停在“获取IP地址”阶段会话迟迟不能进入UP状态。这是我在实验里踩过最深的坑后面排查IP获取问题时会再次提到。VT接口的地址192.168.100.1相当于整个PPPoE接入段的网关地址。客户端拿到的是192.168.100.0/24范围内的另一个地址例如192.168.100.2。2.4 物理接口绑定Virtual-Template最后在连接客户端的物理接口上执行绑定命令interface GigabitEthernet0/0/0 pppoe-server bind virtual-template 1执行完这行后G0/0/0就会开始监听PPPoE发现报文。物理接口上不需要配置IP地址这是很多新手卡住的地方。PPPoE本身是二层会话物理口只负责承载PPPoE报文不参与三层转发。检查绑定后接口状态正常即可。如果确认物理接口Up之后仍然没有响应客户端拨号可以用display pppoe-server session all查看Server侧是否已经有会话记录。没有任何记录时重点排查客户端配置和中间链路看看是不是抓包工具把链路占用了。3. 客户端拨号配置Dialer接口才是主角3.1 Dialer接口和物理接口的分工客户端侧同样存在“逻辑接口”和“物理接口”的分工问题。G0/0/0负责把PPPoE报文实际发送到以太网链路上但PPP协商、认证、IP地址获取这些逻辑过程全部发生在Dialer接口上。Dialer1和G0/0/0之间通过一个dial-bundle-number建立关联匹配编号一致两者才能绑定成一整套拨号通道。这个关系可以理解成打电话Dialer接口是打电话的人决定拨给谁、说什么内容物理接口是电话线只负责传送内容。人在办公室里电话线在外面分工清晰谁也不替代谁。3.2 Dialer接口的完整配置在PPPoE-Client上创建Dialer接口并配置拨号参数sysname PPPoE-Client interface Dialer1 dialer user test dialer bundle 1 ppp pap local-user test password simple 123 ip address ppp-negotiate dialer timer idle 0 mtu 1492逐条拆解一下dialer user test是本地拨号规则标识没有实际发给Server的语义作用但必须有否则拨号规则不完整。dialer bundle 1定义了拨号绑定组1这个组号要与物理接口下的pppoe-client dial-bundle-number 1对应。ppp pap local-user test password simple 123是真正发送给Server做PAP认证的用户名和密码必须和Server侧AAA里配置的账号一致。ip address ppp-negotiate表示通过IPCP动态获取IP地址也就是由Server下发地址。dialer timer idle 0表示空闲时间不挂断连接避免实验过程中链路因为空闲被自动拆除这个参数在实际宽带拨号中也常用。mtu 1492显式指定MTU为1492因为PPPoE额外消耗8字节开销如果仍用1500大包就会因为超过链路载荷能力而产生分片或直接丢弃。3.3 物理接口配置PPPoE Client在物理接口上执行绑定interface GigabitEthernet0/0/0 pppoe-client dial-bundle-number 1这行命令让G0/0/0以PPPoE Client身份主动发起拨号并且指定它属于diag-bundle 1。和Server端不同Client端的物理接口也不需要配置IP地址。IP地址由Dialer1在IPCP协商后获得。这里有个常见误解有人试图在G0/0/0上配置一个同网段的静态IP然后再想办法让Dialer接口工作结果永远拨不上。正确的思路是完全信任逻辑接口物理接口只做二层承载。3.4 内网网关、缺省路由与NATClient还需要同时承担用户内网的网关角色。配置G0/0/1interface GigabitEthernet0/0/1 ip address 192.168.10.1 255.255.255.0这台路由器如果只有内网接口的地址用户PC是无法访问外部网络的因为数据包即使能到Dialer接口出去之后也缺少路由。因此需要配置一条缺省路由指向Dialer接口把所有去向未知网段的数据都引导到PPPoE链路上ip route-static 0.0.0.0 0.0.0.0 Dialer1注意这里指向的是Dialer1而不是G0/0/0因为PPPoE会话建立后所有出接口流量都要通过这个逻辑拨号接口转发。如果写成物理接口数据包会离开以太网接口后在会话层找不到PPP上下文结果就是通了但Ping不稳定甚至完全不通。内网PC的地址是192.168.10.0/24出去后必须被NAT转换成Dialer接口上动态获取到的地址否则Server侧看到的源地址是私网地址回程路由根本不存在。配置NAT使用基本ACL匹配内网网段acl 2000 rule permit source 192.168.10.0 0.0.0.255 interface Dialer1 nat outbound 2000nat outbound 2000的含义是从Dialer1出去的流量如果源地址匹配ACL 2000就做一次动态NAT源地址转换成Dialer1当前获取到的地址。NAT必须配置在Dialer接口而不是物理接口上因为拨号地址是动态变化的只有Dialer接口知道当前会话的地址是什么。如果配置在物理接口上转换后的源地址可能变成一个无效地址外网通信仍然失败。4. 验证链路从状态检查到实际通信4.1 客户端状态检查三步走配置保存后等待几秒让拨号过程完成。在PPPoE-Client上依次执行以下命令检查状态。第一步看拨号会话是否建立display pppoe-client session summary正常情况下应该看到Session State为UP接口是Dialer1同时能看到Session ID。如果显示Connecting或DOWN说明发现阶段或PPP协商还没有完成需要结合后面的排查方法处理。第二步看Dialer接口是否拿到IPdisplay ip interface briefDialer1上应该能看到一个192.168.100.0/24网段的地址例如192.168.100.2。如果Dialer1没有地址说明IPCP协商失败问题大概率出在Server侧没有配置remote address pool或者地址池地址被排除光。第三步直接测试内网设备ping 192.168.100.1这是从Client路由器上发起Ping目标是Server的Virtual-Template地址。如果这个Ping能通说明PPPoE链路本身、PPP协商、认证、IPCP地址下发全部成功。4.2 服务端在线用户与地址池查看在PPPoE-Server上执行以下命令确认服务端视角的会话状态display pppoe-server session all能看到会话ID、客户端MAC、IP地址等信息就说明Server已经维护了一条有效的PPPoE会话。再用以下命令查看认证用户和地址池占用情况display aaa online-user如果看到test用户在线说明PAP认证已经通过。如果这里没有任何用户则问题出在认证环节。继续看地址池display ip pool pppoe_pool used这里能确认当前被分配出去的地址是哪个。地址池有剩余地址说明IPCP分配正常。4.3 端到端通信验证在PC1上执行Ping命令ping 192.168.200.2数据包的完整路径是PC1首先把包发给网关192.168.10.1也就是PPPoE-Client的G0/0/1接口然后路由器匹配缺省路由把包送到Dialer1接口同时做NAT转换封装成PPP帧后通过PPPoE会话送到Server端Server把包从Virtual-Template1路由到G0/0/1接口最终到达PC2。PC2收到的是一个源地址为192.168.100.2的包。这里有一个容易让人困惑的点PC2反向Ping PC1通常是不通的。因为回程的目标地址是192.168.100.2这个地址是PPPoE动态分配地址Server上并没有一条指向这个地址的稳定路由。生产环境中拨号用户普遍是单向访问网络的双向互通需要额外的回程路由设计不会随便配置。5. 抓包观察PPPoE发现与协商过程5.1 抓包前的准备eNSP里抓包非常直接右击Client和Server之间的链路选择抓包即可。但如果拨号已经成功会发现抓包文件里只有零星的PPP保活报文看不到PPPoE的发现过程。这是因为发现阶段只在链路建立的最开始发生错过了就得重新触发生成一次。我在实验里的做法是先开启抓包然后在PPPoE-Client上把G0/0/0接口shutdown再undo shutdown强制物理链路断开再恢复。PPPoE会话随之销毁并重新发起这时抓包窗口就能完整看到发现阶段和PPP协商过程。5.2 发现阶段PADI、PADO、PADR、PADS打开抓包文件后用过滤条件筛选eth.type 0x8863四个关键报文依次出现PADI是客户端以广播地址为目标的发现请求相当于在链路上喊“谁在提供PPPoE服务”。PADO是服务端单播回应的报文相当于“我在这我能提供服务”。PADR是客户端收到PADO后单播发出的正式请求相当于“我确认用你请建立连接”。PADS是服务端回给客户端的最后确认消息中带有Session ID这个ID在后续会话阶段的所有报文中都会出现。建议在四个报文上分别点开看以太网头部里的目的MAC地址。前一个报文是从客户端到广播地址后面几个变成了单播这个变化直观体现了“共享链路中寻找唯一对端”的过程。5.3 会话阶段LCP、PAP、IPCP在抓包文件中继续筛选eth.type 0x8864会话阶段能看到几层协议。首先是通过LCP协商链路参数包括MRU、认证方式等然后是PAP认证报文其中用户名是test密码明文显示是123这也是PAP不安全的最直观证据。之后是IPCP过程客户端发出IP地址请求服务端在回复报文中携带192.168.100.2Dialer接口随即获得地址。建议同时关注LCP协商里的MRU和MTU字段能看到链路协商结果落在1492这个经典值上。IPCP完成之后用户数据才开始走以太网类型的0x8864信道。看完这一整条时间线对PPPoE“先发现、再协商、最后传数据”的流程就非常有画面感了。6. 常见问题速查与排查心得6.1 会话状态一直连不上现象是display pppoe-client session summary显示Connecting始终到不了UP。按以下顺序排查首先检查两端物理接口是否都是Up状态G0/0/0有没有被shutdown然后检查客户端物理接口下的pppoe-client dial-bundle-number值是否和Dialer1的dialer bundle一致最后把抓包工具打开看链路上有没有PADI报文发出。如果没有任何PPPoE报文问题几乎都出在绑定的编号不匹配或物理接口故障上。6.2 认证失败现象是Server侧display aaa online-user为空客户端日志或抓包里能看到PAP被拒绝。最常见原因是Client的ppp pap local-user test password simple 123和Server的local-user test password cipher 123账号密码不一致其次是Server的Local User没有配置service-type ppp。排查时可临时在同一台设备上开启调试debugging ppp event确认认证阶段卡在哪里。实验环境没有问题后记得用undo debugging all关闭调试避免刷屏影响操作。6.3 地址一直获取不到现象是拨号都正常LCP协商和认证都过了但Dialer1迟迟拿不到IP。九成原因是Virtual-Template1上没有配置remote address pool pppoe_pool。地址池没配、网段和VT接口不在同一个范围、地址池里的地址全部被excluded-ip-address排除也会导致完全相同的现象。检查完Server侧再确认Client的Dialer1有没有ip address ppp-negotiate这一行。两者缺一不可。6.4 内网PC不通外网PC1无法Ping通PC2但Client路由器本身可以Ping通192.168.100.1说明PPPoE链路没问题问题出在路由或NAT上。优先检查是不是没有配置缺省路由或者缺省路由指向了物理接口而不是Dialer1再检查NAT是不是写在了Dialer1上ACL匹配到的源地址是不是192.168.10.0/24最后检查PC1的网关是否真的指向192.168.10.1。我见过一例是PC1网关填成了192.168.10.254查了半天才发现是客户端配置错误。6.5 MTU引发的疑难问题现象是小包Ping正常但Ping大包不通或者访问网页时卡顿。PPPoE链路由于PPP和PPPoE头开销用户数据MTU是1492而不是1500。假如Dialer1的MTU仍然是1500发送方会按1500分片接收方在PPP链路发现长度超限大包直接丢失。显式在Dialer接口下配置mtu 1492同时PC端和路由内网接口的MTU保持在默认值不要随意调问题一般就能解决。6.6 其他值得记录的细节模拟器的所有配置都要靠save命令保存重启后才会保留。每次实验完成之后把两台设备的全部配置复制到文本文件存起来下次重建直接粘贴恢复能节省大量时间。实验过程中如果需要改认证方式做对比建议一次只改一个变量比如先把PAP改成CHAP只动认证相关命令其他配置保持不动方便定位变化带来的问题。我个人做完这个实验最大的体会是PPPoE本身不难难的是把逻辑接口和物理接口的关系彻底理清。第一次搭建的时候我在Server上一直纠结物理接口要不要配IP在Client上弄混了dialer user和真正的认证账号结果拨号状态始终不如意。后来打开抓包文件一步步对报文才发现问题都出在最基础的概念上。如果你也打算练这个实验建议把抓包当成最终的验证手段先理解每一个接口的职责再去敲命令会比直接照抄配置有效得多。后面有时间我还想在这个拓扑上把CHAP、多用户同时拨号以及DHCP自动下发这几个场景再补一版到时候再继续分享。