Linux下搭建PPPoEServer问题总结


注:本记录适用于Debian系列Linux操作系统。在Ubuntu 14.10 以及 Linux Mint 17下验证成功。

在综合课程设计的搭建 PPPoE Server 环节中,本人以及组员碰到各种问题。在此总结,以备日后需要。

搭建过程

安装和配置PPPoE程序

PPPoE程序在Debian操作系统中应该是自带的。可以使用 pppoe-server -h 命令查看版本。可以使用 sudo apt-cache search pppoe 查找相关软件。

配置文件存放在 /etc/ppp 文件夹中。先设置 options 文件:

设置 ms-dns的值。要设置成一个可以使用的DNS服务器的IP地址,比如 114.114.114.114 这是Windows主机拨号连接时会分配的DNS地址。 注释掉+pap,取消-pap的注释,这表示不使用pap认证方式。同时,取消+chap的注释,表示使用chap认证方式。

接下来设置 chap-secrets 文件:

按照文件注释的内容,分别填入:用户名 服务器名 密码 IP地址,例如,在最后插入一行:

testing * password *

表示用户名为testing,服务器名为任意,密码为password,IP为任意的IP。

下来,编辑 pppoe-server-options 文件(如果没有,则新建一个1)
在pppoe-server-options里加入:

auth
require-chap
logfile /var/log/pppd.log

这样就配置完毕了。

设置系统的ip策略

开启ip转发功能

使用超级用户的身份,注意,必需是超级用户身份,sudo都没有这个权限,执行:

cat 1 > /proc/sys/net/ipv4/ip_forward

如果单单是执行这个命令,只会暂时开启IP转发功能。重启后会自动关闭。如果想一直打开,则应该编辑 /etc/sysctl.conf 文件,取消 net.ipv4.ip_forward=1 的注释,再执行 sudo sysctl -p 就可以永久打开IP转发功能了。

设置iptables的IP策略

以超级用户身份执行:

iptables -A POSTROUTING -t nat -s 10.10.10.0/24 -j MASQUERADE

注:-s 参数后面的网络地址是一会儿将要开启的pppoe-server设置的网络地址,这个地址可以根据需要自己设定,只要iptables和pppoe-server匹配就好。

运行PPPoE Server

输入:

sudo pppoe-server -I wlan0 -L 10.10.10.1 -R 10.10.10.100 -N 100

注:

-I 参数用于指定监听哪个网络端口。可以使用ifconfig命令查看当前工作的端口名称。由于本人的笔记本电脑使用无线网络,所以是wlan0端口。 -L 参数用于指定在一个PPP连接中,PPPoE服务器的IP地址。由于本人假设的以太网网络地址为10.10.10.0/24,所以就使用网络地址的第一个IP地址作为服务器的地址了。 -R 参数用于指定当有客户连接到服务器上时,从哪个IP地址开始分配给客户。 -N 参数用于指定至多可以有多少个客户同时连接到本服务器上。

如果一切顺利,在Windows上建立拨号连接,用户名和密码分别为testing和password,应该就可以连接到linux下的PPPoE Server上并且正常上网了。

PPPoE 协议过程分析

过程图解

PPPoE协议主要有以下几个过程:

Created with Rapha?l 2.1.2客户客户服务器服务器PADIPADOPADRPADS

解释

主机广播发起分组(PADI),分组的目的地址为以太网的广播地址0×ffffffffffff,CODE(代码)字段值为0×09,SESSION-ID(会话ID)字段值为0×0000。PADI分组必须至少包含一个服务名称类型的标签(标签类型字段值为0×0101),向接入集中器提出所要求提供的服务。 接入集中器收到在服务范围内的PADI分组,发送PPPoE有效发现提供包(PADO)分组,以响应请求。其中CODE字段值为0×07,SESSION-ID字段值仍为0×0000。PADO分组必须包含一个接入集中器名称类型的标签(标签类型字段值为0×0102),以及一个或多个服务名称类型标签,表明可向主机提供的服务种类。 主机在可能收到的多个PADO分组中选择一个合适的PADO分组,然后向所选择的接入集中器发送PPPoE有效发现请求分组(PADR)。其中CODE字段为0×19,SESSION_ID字段值仍为0×0000。PADR分组必须包含一个服务名称类型标签,确定向接入集线器(或交换机)请求的服务种类。当主机在指定的时间内没有接收到PADO,它应该重新发送它的PADI分组,并且加倍等待时间,这个过程会被重复期望的次数。 接入集中器收到PADR分组后准备开始PPP会话,它发送一个PPPoE有效发现会话确认PADS分组。其中CODE字段值为0×65,SESSION-ID字段值为接入集中器所产生的一个唯一的PPPoE会话标识号码。PADS分组也必须包含一个接入集中器名称类型的标签以确认向主机提供的服务。当主机收到PADS分组确认后,双方就进入PPP会话阶段。 PPPoE还有一个PADT分组,它可以在会话建立后的任何时候发送,来终止PPPoE会话,也就是会话释放。它可以由主机或者接入集中器发送。当对方接收到一个PADT分组,就不再允许使用这个会话来发送PPP业务。PADT分组不需要任何标签,其CODE字段值为0×a7,SESSION-ID字段值为需要终止的PPP会话的会话标识号码。在发送或接收PADT后,即使正常的PPP终止分组也不必发送。PPP对端应该使用PPP协议自身来终止PPPoE会话,但是当PPP不能使用时,可以使用PADT。

问题分析

连接时错误

Windows拨号连接显示错误651

可能的原因是没有正确打开服务器。通过WireShark抓包可以看到,Windows在发送了4次PADI报文而没有得到PADO回复后,会报告引错误。

因此,可能是在 pppoe-server 打开时没有指定到正确的网卡。也可能是使用虚拟机上网时没有设置好上网模式,如果没有使用桥接模式上网而是使用了NAT模式,则也可能遇到此问题。

同时,如果没有pppoe-server-options 文件或者该文件没有 auth 和 require-chap 选项设置的话,也会出现这个问题。

同时,该问题也可能是因为在Windows拨号连接时在属性中指定了一个服务器,和linux下开启的PPPoE Server名称不同造成的。

pppoe-server中,-S参数用于指定服务器名称。

Windows拨号连接显示错误734

错误内容为

PPP链接控制协议终止

这个原因可能是在 pppoe-server-options 文件中加入了 login 选项。如果设置了该选项,则登陆的用户名必需和linux系统下的一个用户名相同,否则会出现这个错误。

Windows拨号连接显示错误628

错误内容为

在连接完成前,连接被远程计算机终止

通过WireShark抓包分析,可以看不到在原理分析的四个阶段完成后,立刻收到一个PADT报文。PADT报文的内容描述为:

Generic-Error: RP-PPPOE: child pppd process terminated

这个描述十分有误导性,网上甚至有人说这个需要将pppoe编译进内核,以便可以使用pppoe-server命令的-k参数。后来我发现终究是配置问题,出现了配置错误,一般是出现了程序无法识别的配置。这个错误很麻烦,应当结合刚刚配置的logfile以及自己注释掉一些不确定的命令来排查错误。

无法识别用户名和密码

很可能是用户名和密码输入错误,也可能是设置错误。注意,设置用户名和密码时,两个星号是不能省略的。

上网错误

此类错误是Windows可以拨号连接成功,但是无法上网。主要是在linux下使用 tcpdump 或者 wireshark 程序进行排查。

使用命令:

tcpdump -i wlan0 host 10.10.10.1002
可以看到,只有从主机10.10.10.100发出的报文,但是没有发送给10.10.10.100的报文。

出现这个错误的原因,可能是没有打开IP转发功能。所以当网络上的报文发送给linux主机时,linux主机不会把报文转发给Windows主机,而是由于目的地址不是自己而直接丢弃。

同时也可能是没有设置iptables 的POSTROUTING的nat规则。

网络拓扑相关问题

一般是在虚拟机上安装一个linux操作系统,搭好PPPoE Server。然后在宿主机上进行连接测试。则有以下几个问题:

如果虚拟机采用NAT模式,则宿主机无法登陆。因为NAT模式下,宿主机是无法与虚拟机通信的。各种模式下的通信功能见下图:这里写图片描述vc7KzOLU2cztvNOwyaGj1+7W2NKqtcTKx8DtveK497j2sr3W6LrN0K3S6bXE1K3A7aOs1eLR+bLFxNy/7MvZxcWy6bTtzvO1xNSt0vKhozwvcD4KCjxocj48bGkgaWQ9"fn:footnote">这个问题困扰了我很久。网上说是编辑这个文件,但是在操作系统中没有这个文件,我一直以为是版本的问题,后来才发现需要自己新建。这个和.vimrc以及.bashrc等文件是一样的。 ?
  • -i用于指定端口,host指定的ip应该在windows用ipconfig查看得到,可能不一样。 ?
  • 相关内容