ToB企服应用市场:ToB评测及商务社交产业平台

标题: 网络网络层之(7)PPPOE协议 [打印本页]

作者: 千千梦丶琪    时间: 2024-6-15 00:19
标题: 网络网络层之(7)PPPOE协议
网络网络层之(7)PPPOE协议

  
   Author: Once Day Date: 2024年4月7日


  一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦…


   漫漫长路,有人对你微笑过嘛…


  全系列文档可参考专栏:通信网络技术_Once-Day的博客-CSDN博客。


  参考文章:
  
  

  
1. 概述

1.1 PPPoE先容

PPPoE,全称为点对点协议通过以太网(Point-to-Point Protocol over Ethernet),是一种在以太网上运行的封装协议,它答应将点对点协议(PPP)帧通过以太网封装并传输。这种技术最早是为了实现通过简单的以太网连接来接入互联网的宽带接入服务,尤其是在DSL(数字用户线)服务中得到了广泛应用。
PPPoE结合了以太网和PPP的特点,既有以太网简单的网络搭建特性,又有PPP支持的认证、加密和压缩功能
PPPoE协议答应用户在现有的网络架构上进行小改动即可接入互联网,这大大低落了成本和技术门槛。用户通过PPPoE连接到互联网时,会履历认证过程,这通常需要账号和密码,确保了连接的合法性和安全性。这种认证机制让宽带服务商可以大概轻松管理用户的接入,并且提供计费服务。
PPPoE一般具有如下长处:

然而,PPPoE也有其局限性,如下所示:

在欧洲一些老修建内,PPPoE可以最大程度使用原有电信线路来实现高性能网络通信。在国内的网吧和公司里面,运营商的专线也需要该技术提供支持。对于运营商而言,则可以通过访问控制功能对用户的身份进行确认,以及通过计费功能对用户进行计费,同时对用户的网络行为进行监控。
1.2 常见拓扑场景

PPPoE一般有两种摆设场景,如下所示:

第一种摆设场景是运营商摆设场景。在这个模型中,运营商负责摆设PPPoE服务器。用户通过电话线路连接到DSLAM(Digital Subscriber Line Access Multiplexer,数字用户线接入复用器),DSLAM再通过高速互联网连接至运营商的PPPoE服务器。
用户端则需要一个DSL调制解调器(Modem),其负责将电话线路的模仿信号转换成数字信号,然后通过PPPoE协议进行认证,建立网络连接。一旦认证乐成,用户的电脑便通过DSL调制解调器连接到互联网。
运营商摆设方式常见于家庭或小型办公室,可以将单一的互联网连接共享给多个装备使用
第二种摆设场景是是将PPPoE客户端拨号的责任下放到用户的每一台主机(Host)上。每个Host作为一个PPPoE客户端,都需要进行单独的验证和会话管理。
一旦建立连接,运营商的路由器就能辨认出来自该主机的流量,并根据用户的账号进行相应的计费和流量控制。
PPPoE客户端下放摆设方式通常用于小型办公室、网吧大概学校等环境,这些场合需要对用户进行严格的带宽和使用时间控制
2. PPPoE报文

2.1 PPPoE报文格式

PPPoE报文基本上由两部分组成:以太网头部和PPP会话数据。以太网头部用于辨认数据包类型和目的地,而PPP会话数据则承载了实际的PPP通信内容。
PPP报文的格式可以参考文章:网络链路层之(2)PPP协议_ppp协议工作状态传输数据-CSDN博客。
PPPoE协议是基于以太网的,而以太网自己已经具有帧控制和地址指定的功能,因此PPP的地址和控制字段被省略了。以是PPPoE报文主要包含以下几个部分:

PPPoE报文具体格式如下图所示:

PPPoE报文各字段表明如下:

PPP报文里的协议字段内容和PPPoE是互不相干的,这部分可以直接参考标准PPP协议内容。
3. PPPOE工作过程

PPPoE可分为三个阶段,即Discovery阶段、Session阶段和Terminate阶段。
可以参考华为IP知识百科里面的一张时序图(什么是PPPoE?PPPoE解决了哪些标题? - 华为 (huawei.com)):

在发现(Discovery)阶段,PPPoE客户端(通常是家庭网络中的路由器或个人计算机)向本地网络发送一个广播消息,探求PPPoE服务提供商的接入集中器(Access Concentrator,AC),如下所示:
如果发现阶段统统正常,PPPoE就会根据最后生成的Session ID创建一个点对点会话,并开始会话阶段。
在会话(Session)阶段,首先进入PPP会话协商阶段,包括LCP协商、用户认证和网络配置协商(IP地址等)等。完成PPP协商之后,便可以开始传输IP数据报文。
最后一个是终止(Terminate)阶段。PPPoE Client和PPPoE Server都可以通过发送PADT报文的方式来竣事PPPoE连接。PADT报文可以在会话建立以后的恣意时候单播发送。
4. PPPoE和IPoE和区别和联系

可参考华为IP知识文档: 什么是PPPoE?PPPoE解决了哪些标题? - 华为 (huawei.com)。
PPPoE(PPP over Ethernet )和IPoE(IP over Ethernet )是两种常见的宽带接入方法:

下面是一个对比表格,简单列出了PPPoE与IPoE的主要区别和联系:
特性PPPoEIPoE身份验证需要用户名和密码通常不需要身份验证协议封装PPP封装在以太网帧中直接使用IP封装在以太网帧中IP分配通过PPP协议通常通过DHCP协议连接建立分阶段过程(发现、会话、关闭)直接通过DHCP进行使用场景常用于DSL宽带连接适用于更广泛的以太网连接安全性较高,支持多种身份验证方法依靠于网络其他安全机制配置复杂度较复杂,需要客户端软件支持较简单,通常不需要额外配置性能影响由于封装,可能会有轻微性能损失通常性能损失较小兼容性需要支持PPPoE的装备和软件以太网装备通常默认支持功能支持支持更多PPP特性,如压缩、加密等侧重于简洁的IP层连接 PPPoE具备认证能力,因此常用于运营商提供宽带接入端点。IPoE能自主管理IP地址使用,未限制组播能力,常用于局域网范围内提供网络接入端。IPoE需要配合其他协议提供认证能力,同时也需要其他网络装备(网关、防火墙等)提供安全能力支持。
5. Linux ubuntu上配置PPPoE服务器

5.1 Linux内核支持pppoe协议

PPPoE (Point-to-Point Protocol over Ethernet) 需要内核支持以下几个主要配置:
功能配置宏描述PPP (Point-to-Point Protocol)CONFIG_PPPPPPoE 基于 PPP 协议,因此内核必须启用通用的 PPP 支持。PPP over EthernetCONFIG_PPPOE专门启用 PPPoE 功能,答应 PPP 数据包通过以太网传输。PPP 异步控制字符映射CONFIG_PPP_ASYNC启用此选项可支持异步 PPP 链路,这是 PPPoE 所必需的。PPP 同步控制字符映射CONFIG_PPP_SYNC_TTY此选项为同步 PPP 链路提供支持,某些 PPPoE 实现可能需要它。PPP 压缩支持(可选)CONFIG_PPP_DEFLATE
CONFIG_PPP_BSDCOMP启用 PPP 压缩功能,可以提高 PPPoE 连接的效率,但不是必需的。PPP over L2TP 支持(可选)CONFIG_PPPOL2TP如果需要通过 L2TP 隧道传输 PPPoE,则需要启用此选项。 在 Linux 内核的 make menuconfig 配置界面中,这些选项通常位于以下位置:
  1. Device Drivers  --->
  2.   [*] Network device support  --->
  3.     <*>   PPP (point-to-point protocol) support
  4.     <*>     PPP over Ethernet
  5.     <*>     PPP support for async serial ports
  6.     <*>     PPP support for sync tty ports
  7.     <*>     PPP Deflate compression
  8.     <*>     PPP BSD-Compress compression
  9.     <*>   PPP over L2TP
复制代码
在实际运行的ubuntu服务器上,可以查抄/boot目录下配置文件,如下:
  1. onceday
  2. @ubuntu2:~$ cat /boot/config-5.15.0-100-generic |grep PPP
  3. CONFIG_PPP=y
  4. CONFIG_PPP_BSDCOMP=m
  5. CONFIG_PPP_DEFLATE=m
  6. CONFIG_PPP_FILTER=y
  7. CONFIG_PPP_MPPE=m
  8. CONFIG_PPP_MULTILINK=y
  9. CONFIG_PPPOATM=m
  10. CONFIG_PPPOE=m
  11. CONFIG_PPPOL2TP=m
  12. CONFIG_PPP_ASYNC=m
  13. CONFIG_PPP_SYNC_TTY=m
  14. CONFIG_HDLC_PPP=m
复制代码
这是VirtualBox虚拟机里的ubuntu 22.04服务器,PPPoE内核相关支持非常完整,如果缺少这些配置,需要重新编译内核才行。
5.2 查抄Ubuntu的PPPoE支持情况

首先查抄内核中是否支持了PPPoE协议,查看/proc/net/protocols文件,如下:
  1. onceday
  2. @ubuntu2:~$ cat /proc/net/protocols
  3. protocol  size sockets  memory press maxhdr  slab module
  4. PACKET    1600      1      -1   NI       0   no   kernel
  5. MPTCPv6   2008      0       1   no       0   yes  kernel
  6. PINGv6    1208      0      -1   NI       0   yes  kernel
  7. RAWv6     1208      1      -1   NI       0   yes  kernel
  8. UDPLITEv6 1344      0       2   NI       0   yes  kernel
  9. UDPv6     1344      1       2   NI       0   yes  kernel
  10. TCPv6     2384      1       1   no     320   yes  kernel
  11. XDP       1024      0      -1   NI       0   no   kernel
  12. UNIX-STREAM 1088    109      -1   NI       0   yes  kernel
  13. UNIX      1088     43      -1   NI       0   yes  kernel
  14. UDP-Lite  1152      0       2   NI       0   yes  kernel
  15. MPTCP     1848      0       1   no       0   yes  kernel
  16. PING      1000      0      -1   NI       0   yes  kernel
  17. RAW       1008      0      -1   NI       0   yes  kernel
  18. UDP       1152      2       2   NI       0   yes  kernel
  19. TCP       2224      3       1   no     320   yes  kernel
  20. NETLINK   1136     20      -1   NI       0   no   kernel
复制代码
一般默认情况下,ubuntu都是未加载PPPoE模块到内核中,因此上述是没有PPPoE协议。如果已经存在PPPoE协议,可以直接跳过这一节
接下来,直接使用modprobe加载PPPoE内核模块,如下:
  1. onceday
  2. @ubuntu2:~$ sudo modprobe pppoe
  3. onceday
  4. @ubuntu2:~$ lsmod
  5. Module                  Size  Used by
  6. pppoe                  20480  0
  7. pppox                  16384  1 pppoe
  8. ...(省略)...
  9. onceday
  10. @ubuntu2:~$ cat /proc/net/protocols
  11. protocol  size sockets  memory press maxhdr  slab module     
  12. PPPOE      960      0      -1   NI       0   no   pppoe
  13. ...(省略)...
复制代码
Shell输出中已经包含PPPoE相关信息,说明内核已加载相应的模块,目前可支持PPPoE功能。
留意,上面只是让内核支持 PPPoE,要看到PPPoE连接和接口,还需要正确使用用户空间工具配置PPPoE客户端大概服务器。
5.3 ubuntu上配置PPPoE服务器

参考文档:

首先安装PPPoE服务器软件包ppp和pppoe,然后就可以看到一系列相关的下令工具:
  1. onceday
  2. @ubuntu2:~$ sudo apt install ppp pppoe
  3. onceday
  4. @ubuntu2:~$ ppp
  5. pppd             pppoe            pppoe-discovery  pppoe-server     pppoe-start      pppoe-stop      
  6. pppdump          pppoe-connect    pppoe-relay      pppoe-sniff      pppoe-status     pppstats   
复制代码
然后编辑/etc/ppp/pppoe-server-options文件,配置PPPoE服务器选项:
  1. # 启用调试模式
  2. debug
  3. # 服务器名称
  4. name "My PPPoE Server"
  5. # 启用身份验证
  6. login
  7. auth
  8. # 要求客户端使用CHAP身份验证
  9. require-chap
  10. # 设置空闲超时时间为600秒
  11. idle 600
  12. # 为客户端分配DNS服务器
  13. ms-dns 8.8.8.8
复制代码
编辑/etc/ppp/pppoe-allowed文件,添加答应登录的用户名:
  1. onceday
复制代码
编辑/etc/ppp/chap-secrets文件,添加PPPoE用户认证信息:
  1. onceday
  2.   *   "123456"  *
复制代码
启动 PPPoE 服务,设置服务器实际使用的网卡接口名,并且指定PPPoE服务器的本地IP地址和远程IP地址:
  1. sudo pppoe-server -I enp0s9 -L 192.168.0.103 -R 192.168.0.200 -N 10
复制代码
完成以上配置操纵之后,用户onceday
就可以使用账号onceday
,密码123456拨号连接到该PPPoE服务器了。
客户端需要编辑对应的配置文件
  1. # PPPoE客户端配置文件# 使用debug模式DEBUG=1# 以太网接口名称,根据实际情况修改ETH=enp0s9# PPPoE用户名USER="onceday
  2. "# PAP/CHAP身份验证的密码PASSWORD="123456"# 不启用默认路由DEFAULTROUTE=no# 担当服务器分配的DNS服务器地址PEERDNS=yes# 启用持久化连接PERSIST=yes# 设置 LCP echo 请求帧发送的时间隔断(以秒为单元)LCP_INTERVAL=1# 设置在多少个 LCP echo 请求失败后断开连接LCP_FAILURE=10# 最大报文负载, 不指定CLAMPMSS=no# PPPOE会话超时时间PPPOE_TIMEOUT=3600
复制代码
在客户端上,也要编辑/etc/ppp/chap-secrets文件,添加PPPoE用户认证信息:
  1. onceday
  2.   *   "123456"  *
复制代码
然后启动pppoe-connect连接到服务端,等待自动配置完全即可,如下:
  1. onceday
  2. @ubuntu1:~$ sudo pppoe-connect /usr/sbin/pppoe-connect: 121: test: Illegal number: /usr/sbin/pppoe-connect: 307: cannot create : Directory nonexistentUsing interface ppp0Connect: ppp0 <--> /dev/pts/5CHAP authentication succeeded: Access grantedCHAP authentication succeededlocal  LL address fe80::844d:9f7c:662a:4617remote LL address fe80::7c4f:5d0c:3ecd:7c08BSD-Compress (15) compression enabledlocal  IP address 192.168.0.209remote IP address 192.168.0.103primary   DNS address 8.8.8.8secondary DNS address 8.8.8.8CCP terminated by peer (Lost compression sync)Compression disabled by peer.
复制代码
到此,这条PPPoE隧道就正常搭建完成,可以在客户端上Ping服务端IP测试连通性,如下:
  1. onceday
  2. @ubuntu1:~$ ping 192.168.0.103PING 192.168.0.103 (192.168.0.103) 56(84) bytes of data.64 bytes from 192.168.0.103: icmp_seq=1 ttl=64 time=1.27 ms64 bytes from 192.168.0.103: icmp_seq=2 ttl=64 time=0.703 ms
复制代码
如果想在服务端进行隧道报文转发,还需配置路由和开启相关的网络配置,这些就不继续深究了,感爱好的可以自行研究。
5.4 PPPoE服务器和客户端的交互流程

在PPPoE拨号连接建立过程中,服务器和客户端都会自动发送数据包。
首先是客户端(PPPoE Client)发起连接,客户端广播发送 PPPoE Active Discovery Initiation (PADI) 数据包,探求可用的PPPoE服务器。服务器(PPPoE Server)相应连接请求:
  1. 17:04:52.902923 PPPoE PADI [Service-Name] [Host-Uniq "112b"]
  2.         0x0000:  ffff ffff ffff 0800 2793 6f37 8863 1109
  3.         0x0010:  0000 000c 0101 0000 0103 0004 3131 3262
  4. 17:04:52.903557 PPPoE PADO [AC-Name "ubuntu2"] [Service-Name] [AC-Cookie 0x1C1FBC31407E62C34EEB9047F2315AF556430000] [Host-Uniq "112b"]
  5.         0x0000:  0800 2793 6f37 0800 2756 7b06 8863 1107
  6.         0x0010:  0000 002f 0102 0007 7562 756e 7475 3201
  7.         0x0020:  0100 0001 0400 141c 1fbc 3140 7e62 c34e
  8.         0x0030:  eb90 47f2 315a f556 4300 0001 0300 0431
  9.         0x0040:  3132 62
  10. 17:04:52.903600 PPPoE PADR [Service-Name] [Host-Uniq "112b"] [AC-Cookie 0x1C1FBC31407E62C34EEB9047F2315AF556430000]
  11.         0x0000:  0800 2756 7b06 0800 2793 6f37 8863 1119
  12.         0x0010:  0000 0024 0101 0000 0103 0004 3131 3262
  13.         0x0020:  0104 0014 1c1f bc31 407e 62c3 4eeb 9047
  14.         0x0030:  f231 5af5 5643 0000
  15. 17:04:52.914654 PPPoE PADS [ses 0x3] [Service-Name] [Host-Uniq "112b"]
  16.         0x0000:  0800 2793 6f37 0800 2756 7b06 8863 1165
  17.         0x0010:  0003 000c 0101 0000 0103 0004 3131 3262
  18.         0x0020:  0000 0000 0000 0000 0000 0000 0000 0000
  19.         0x0030:  0000 0000 0000 0000 0000 0000
复制代码
从抓包可以看到这个过程,首先是客户端发送一个广播报文,然后服务端发送单播报文回应请求。接下来,客户端从收到的PADO包中选择一个服务器,单播发送 PPPoE Active Discovery Request (PADR) 数据包给选中的服务器,请求建立连接。
PADS包中包含会话ID等信息,后续数据包都使用该ID标知趣应的PPPoE会话,完成认证阶段和网络层配置之后,就可以进行正常的数据报文传输了。下面是服务端的日志信息,能清晰看到配置协商过程:
  1. pppd[17696]: Connect: ppp0 <--> /dev/pts/1pppd[17696]: sent [LCP ConfReq id=0x1 <mru 1492> <auth chap MD5> <magic 0x7a0751d7>]pppd[17696]: rcvd [LCP ConfReq id=0x1 <mru 1492> <magic 0x6a2ef77b>]pppd[17696]: sent [LCP ConfAck id=0x1 <mru 1492> <magic 0x6a2ef77b>]pppd[17696]: rcvd [LCP ConfAck id=0x1 <mru 1492> <auth chap MD5> <magic 0x7a0751d7>]pppd[17696]: sent [LCP EchoReq id=0x0 magic=0x7a0751d7]pppd[17696]: sent [CHAP Challenge id=0xb2 <4a478a7ef6cc9b30b6143f24eaf79f7dd8645fc3>, name = "My PPPoE Server"]pppd[17696]: rcvd [LCP EchoReq id=0x0 magic=0x6a2ef77b]pppd[17696]: sent [LCP EchoRep id=0x0 magic=0x7a0751d7]pppd[17696]: rcvd [LCP EchoRep id=0x0 magic=0x6a2ef77b]pppd[17696]: rcvd [CHAP Response id=0xb2 <87e5fd4d32629e5725456db7f991a3e9>, name = "onceday
  2. "]pppd[17696]: sent [CHAP Success id=0xb2 "Access granted"]pppd[17696]: Initializing PAM (2) for user onceday
  3. pppd[17696]: ---> PAM INIT Result = 0pppd[17696]: Attempting PAM account checkspppd[17696]: PAM Account OK for onceday
  4. pppd[17696]: PAM Session opened for user onceday
  5. pppd[17696]: user onceday
  6. logged in on tty  intf ppp0kernel: [ 8279.438121] PPP BSD Compression module registeredpppd[17696]: local  LL address fe80::7c4f:5d0c:3ecd:7c08pppd[17696]: remote LL address fe80::844d:9f7c:662a:4617kernel: [ 8279.445750] PPP Deflate Compression module registeredkernel: [ 8279.448512] ppp0: ppp: compressor dropped pktsystemd-networkd[15451]: ppp0: Link UPsystemd-networkd[15451]: ppp0: Gained carrierpppd[17696]: BSD-Compress (15) compression enabledsystemd-networkd[15451]: ppp0: Gained IPv6LLpppd[17696]: local  IP address 192.168.0.103pppd[17696]: remote IP address 192.168.0.209pppd[17696]: Lost compression sync: disabling compression
复制代码
在客户端的接口信息如下:
  1. 50: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN group default qlen 3
  2.     link/ppp
  3.     inet 192.168.0.209 peer 192.168.0.103/32 scope global ppp0
  4.        valid_lft forever preferred_lft forever
  5.     inet6 fe80::844d:9f7c:662a:4617 peer fe80::7c4f:5d0c:3ecd:7c08/128 scope link
  6.        valid_lft forever preferred_lft forever
复制代码
服务端接口信息如下:
  1. 48: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN group default qlen 3
  2.     link/ppp
  3.     inet 192.168.0.103 peer 192.168.0.209/32 scope global ppp0
  4.        valid_lft forever preferred_lft forever
  5.     inet6 fe80::7c4f:5d0c:3ecd:7c08 peer fe80::844d:9f7c:662a:4617/128 scope link
  6.        valid_lft forever preferred_lft forever
复制代码
6. 总结

虽然PPPoE是很久远的技术,并且目前除了特定的运营商场合,其他场景下使用频率较低。但是作为初代的点对点协议,PPPoE影响了很多后续的VPN和隧道协议设计工作。明白PPPoE的工作原理,对掌握GRE/IPsec/SSLVPN/L2TP等新一代VPN隧道协议有较大帮助。
PPPoE会话建立工作流程主要包括四步:

完成以上四步之后,便可以开始传递会话数据了,这个阶段也会有LCP协议报文传输,并不全都是数据报文。
如果发生了非常大概特殊情况,PPPoE两边都可以发送PADT终止报文,一旦收到这个报文,相关会话便会被打扫掉。
在PPPoE会话建立之后,通常装备上也会出现pppx接口,作为一个虚拟三层IP子接口,用于承接实际的网络数据流量和各种配置。
受限于个人水平和能力,上述内容难免存在错误,还请各位大佬海涵,并不吝赐教,感谢支持!







   Once Day

  

    也信美人终作土,不堪幽梦太急遽......
    如果这篇文章为您带来了帮助或启发,不妨点个赞




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4