1.安装rp-pppoe
测试环境:
- PPPoe Server:Ubuntu 20.04
- PPPoe Client:Windows 11
首先,我们先安装PPPoe服务器,我们需要下载rp-pppoe的源码,然后自行编译安装。在安装之前需要安装编译所需要的包。
apt-get install python3 python-dev python3-dev
apt-get install build-essential libssl-dev libffi-dev
apt-get install libxml2-dev libxslt1-dev zlib1g-dev
下载rp-pppoe并安装
wget https://dianne.skoll.ca/projects/rp-pppoe/download/rp-pppoe-3.15.tar.gz
tar zxvf rp-pppoe-3.15.tar.gz
cd rp-pppoe-3.15
cd src
./configure
make
make install
2.配置rp-pppoe
(1)打开ipv4/ipv6转发
使用超级用户身份开启ip转发策略
echo 'net.ipv6.conf.all.forwarding = 1' >> /etc/sysctl.conf
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
或者永久开启在/etc/sysctl.conf中取消net.ipv4.ip_forward = 1 /net.ipv6.conf.all.forwarding = 1的注释
(2)修改配置文件
打开/etc/ppp/pppoe.conf
修改下面几个值,其他的不要动
ETH=eth0
USER=rp-pppoe
vi /etc/ppp/pppoe-server-options
#login
auth
lcp-echo-interval 10
lcp-echo-failure 2
+ipv6
ipv6 ::1,::2
logfile /var/log/pppd.log
#require-pap
login:如果启用login,那么要通过PPPoE认证的用户名需要和虚拟机中的一个用户名相同才能验证成功,否则会出现734错误
+chap:表示使用chap方式认证
auth:表示要认证才能登录
lcp-echo-interval:表示LCP-Echo数据包发送的时间间隔
lcp-echo-failure:表示LCP-Echo失败尝试的次数
ms-dns:表示客户端windows系统下DNS的地址
logfile:日志系统的位置
plugin:加载rp-pppoe.so插件
配置账号密码
vi /etc/ppp/chap-secrets
##
"test" * "test" *
##
vi /etc/ppp/pap-secrets
##
"test" * "test"
##
(3)打开防火墙
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
(4)启动pppoe server
pppoe-server -I eth0 -L 192.168.5.1 -R 192.168.5.5 -N 10 -H https://acs1.dsl.it:7006/cwmpWeb/CPEMgt -M provcode=B7A4E1C43940F4B5,mng_IPv6=0,ntp1=10.10.10.1,ntp2=10.10.10.2
-I eth0 指定pppoe服务器在那个网卡接口监听连接请求
-L 192.168.5.1 指定pppoe服务器的ip地址。(注意:此IP地址不是网卡的IP地址,而是PPPOE服务器的虚拟IP)(此地址可以任意)
-R 192.168.5.5 pppoe服务器分配给客户端的IP地址,从192.168.5.5开始,递增
-N 10 指定最多可以连接pppoe服务器的客户端数量(默认是64 最大是65534)
-C: 用于指定你的PPPoE服务器主机名(此参数可以不要)
-S: 该选项用于标记特定的服务器,以帮助客户端系统对pppoe服务器进行自我标定。-S选项经常用来保证一些特定客户始终连接到特定服务器,特别是当你的网络上有多个pppoe服务器时。 PPPoE协议的客户端软件可被配置为只登陆有"特殊服务名称"的pppoe服务器。如果客户端指定的服务器名称与-S选项服务名称中宣称的名字相符,就会连接到该服务器。
-T: 超时时间(设置为60秒)
-H:在PADM包中以HURL标签发送url。
-M:在PADM包的MOTM标签中发送msg。
pppoe-servr -help
Options:
-I if_name -- Specify interface (default eth0.)
-T timeout -- Specify inactivity timeout in seconds.
-C name -- Set access concentrator name.
-m MSS -- Clamp incoming and outgoing MSS options.
-L ip -- Set local IP address.
-l -- Increment local IP address for each session.
-R ip -- Set start address of remote IP pool.
-S name -- Advertise specified service-name.
-O fname -- Use PPPD options from specified file
(default /etc/ppp/pppoe-server-options).
-p fname -- Optain IP address pool from specified file.
-N num -- Allow 'num' concurrent sessions.
-o offset -- Assign session numbers starting at offset+1.
-f disc:sess -- Set Ethernet frame types (hex).
-s -- Use synchronous PPP mode.
-X pidfile -- Write PID and lock pidfile.
-q /path/pppd -- Specify full path to pppd.
-Q /path/pppoe -- Specify full path to pppoe.
-u -- Pass 'unit' option to pppd.
-r -- Randomize session numbers.
-d -- Debug session creation.
-x n -- Limit to 'n' sessions/MAC address.
-P -- Check pool file for correctness and exit.
-i -- Ignore PADI if no free sessions.
-M msg -- Send MSG in a MOTM tag in PADM packet after PADS.
-H url -- Send URL in a HURL tag in PADM packet after PADS.
-h -- Print usage information.
3.配置rp-pppoe支持ipv6
rp-ppppoe支持ipv6,但需要和radvd搭配使用
安装radvd
apt install radvd
配置文档vi /etc/radvd.conf
interface ppp0 {
AdvSendAdvert on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
AdvOtherConfigFlag on;
AdvManagedFlag on;
prefix 2022:1:2:3::/64 {
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
AdvValidLifetime 500;
AdvPreferredLifetime 200;
};
RDNSS 2022:1:2:3::1 {
AdvRDNSSLifetime 300;
};
};
启动
service radvd start
4.rp-pppoe docker images 制作
dockerfile
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND noninteractive
COPY rp-pppoe-3.15.tar.gz /rp-pppoe-3.15.tar.gz
COPY sysctl.conf /sysctl.conf
COPY pppoe-server-options /pppoe-server-options
COPY pppoe.conf /pppoe.conf
COPY chap-secrets /chap-secrets
COPY pap-secrets /pap-secrets
COPY radvd.conf /radvd.conf
RUN set -x \
&& apt-get update --fix-missing \
&& apt-get install --no-install-recommends -y net-tools vim curl git iproute2 wget inetutils-ping bridge-utils iptables ppp \
&& apt-get install --no-install-recommends -y build-essential cmake gcc g++ build-essential \
&& apt-get install --no-install-recommends -y flex bison libmysqlclient-dev make libcurl4-openssl-dev libxml2-dev libpcre3-dev libncurses5-dev libreadline-dev uuid-dev \
&& apt-get install --no-install-recommends -y libssl-dev libffi-dev libxslt1-dev zlib1g-dev radvd \
&& tar -zxvf rp-pppoe-3.15.tar.gz \
&& cd /rp-pppoe-3.15/src \
&& ./configure \
&& make \
&& make install \
&& cp /sysctl.conf /etc/sysctl.conf \
&& sysctl -p \
&& cp /pppoe-server-options /etc/ppp/pppoe-server-options \
&& cp /pppoe.conf /etc/ppp/pppoe.conf \
&& cp /chap-secrets /etc/ppp/chap-secrets \
&& cp /pap-secrets /etc/ppp/pap-secrets \
&& cp /radvd.conf /etc/radvd.conf \
&& rm -f /rp-pppoe-3.15.tar.gz \
&& rm -f /sysctl.conf \
&& rm -f /pppoe-server-options \
&& rm -f /pppoe.conf \
&& rm -f /chap-secrets \
&& rm -f /pap-secrets \
&& rm -f /radvd.conf
5.问题分析
连接时错误
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 eth0 -w pppoe.cap
可以看到,只有从主机发出的报文,但是没有发送给客户端的报文。
出现这个错误的原因,可能是没有打开IP转发功能。所以当网络上的报文发送给linux主机时,linux主机不会把报文转发给Windows主机,而是由于目的地址不是自己而直接丢弃。
同时也可能是没有设置iptables 的POSTROUTING的nat规则。