accel-ppp 搭建 PPPoE 服务器完整教程(VMware 实战版)
accel-ppp 搭建 PPPoE 服务器完整教程(VMware 实战版)
目标:把一台 Linux 虚拟机变成”宽带认证服务器”(BRAS),Windows 虚拟机用系统自带的”宽带连接(PPPoE)”输入账号密码即可拨号上网,流量经服务器 NAT 出公网。
基于 官方仓库 master 分支 源码编译;配置中所有关键字段(
[ip-pool]、[dns]、模块名等)均已对照源码与 man 手册核实。第 10 章是本次实战的真实踩坑记录(含日志证据、源码依据),以后排错可直接对照。
目录
- 原理速览
- 实验环境与网络规划
- 编译安装 accel-ppp
- 配置文件 /etc/accel-ppp.conf(最终版,逐行注释)
- 账号文件 /etc/ppp/chap-secrets
- NAT 转发(客户端上外网的关键)
- 启动服务(前台 / systemd)
- Windows 客户端拨号
- 验证(三层递进)
- 踩坑实录(5 个真实故障)
- 日常运维命令
- 故障速查表
- 附录:纯净版配置(可直接粘贴)
1. 原理速览
1.1 PPP 与 PPPoE 的关系
- PPP(Point-to-Point Protocol):点对点链路层协议,与底层介质无关。一次连接分三步:
- LCP:协商链路参数(MRU、认证方式等)
- 认证:PAP / CHAP / MSCHAPv2
- NCP(IPCP):分配 IP 地址、DNS
- PPPoE = PPP over Ethernet(RFC 2516):以太网上没有”点对点”概念,所以先要发现对方,再在二者之间跑 PPP。家庭宽带的”宽带拨号上网”就是它。
1.2 一次完整拨号的报文流程
客户端(Windows) 服务器(accel-ppp) |
- AC-Cookie:服务器在 PADO 里塞一个随机 cookie,客户端 PADR 必须原样带回,用于防伪造/防 DDoS。如果日志报
incorrect AC-Cookie,几乎一定是同一二层里有两个服务器在应答(见踩坑 2)。 - 各平台都能拨:Windows 自带”宽带连接”;Linux 用 pppd + rp-pppoe;macOS 在网络设置里添加 PPPoE 服务;家用路由器 WAN 口的”宽带拨号上网”本质就是 PPPoE 客户端。
1.3 路由器 WAN 口各种”拨号”对照
| 路由器 WAN 类型 | 实际协议 | 说明 |
|---|---|---|
| PPPoE(宽带拨号上网) | PPP over Ethernet | 国内家庭宽带最常见,需账号密码 |
| PPPoA | PPP over ATM | 老 ADSL 时代 |
| 动态 IP(自动获得) | DHCP / IPoE | 无认证,或运营商做 MAC 绑定 |
| 静态 IP | 手工配置 | 专线 |
| L2TP / PPTP | VPN 二次拨号 | 部分地区大内网(如学校)再套一层认证 |
2. 实验环境与网络规划
| 角色 | 系统 | 网卡 | 说明 |
|---|---|---|---|
| PPPoE 服务器 | Linux VM(Debian/Ubuntu) | ens33 | accel-ppp 监听 + NAT 出口 |
| PPPoE 客户端 | Windows 10/11 VM | 以太网 | 用系统”宽带连接”拨号 |
VMware 网络要求:
- 两台 VM 挂在同一个 VMnet(PPPoE 发现阶段靠以太网广播,必须同二层);
- 服务器 VM 自身要能上网(VMnet 选 NAT 模式,或桥接到宿主网络均可)。
地址规划(与本次联调环境一致):
| 项目 | 值 |
|---|---|
| 客户端地址池 | 10.10.10.10 - 10.10.10.254 |
| 服务器侧网关 IP | 10.10.10.1 |
| 下发 DNS | 223.5.5.5 / 114.114.114.114 |
| 测试账号 | user1 / pass123 |
| AC 名称 | accel-bras(随意) |
| 监听网卡 | ens33 |
双网卡方案:想让”PPPoE 接入面”与”上联面”分离(更接近真实 BRAS),给服务器加第二块网卡,
interface=写接入网卡,iptables-o写上联网卡。本教程按单网卡(ens33 兼两职,VMware NAT 型 VMnet)记录。
3. 编译安装 accel-ppp
3.1 安装依赖(Debian/Ubuntu)
apt-get update |
3.2 编译
git clone --depth 1 -b master https://github.com/accel-ppp/accel-ppp.git |
BUILD_IPOE_DRIVER/BUILD_VLAN_MON_DRIVER是 IPoE 与 VLAN 监控的内核驱动,纯 PPPoE 实验可不带;带上才需要-DKDIR内核头文件路径。- 仓库地址就是官方上游
https://github.com/accel-ppp/accel-ppp.git,master 分支,无需 fork。
3.3 安装产物清单
/usr/sbin/accel-pppd # 主程序 |
排查提示:日志若报
can't load module xxx,先ls /usr/lib64/accel-ppp/确认该.so存在。本环境模块分布在auth/、extra/、ipv6/、logs/、radius/、shaper/、triton/、vlan-mon/子目录。
3.4 目录准备
mkdir -p /var/log/accel-ppp |
4. 配置文件 /etc/accel-ppp.conf(最终版,逐行注释)
这是本次联调跑通后的最终配置,直接照抄即可(注意第 5 章的账号文件):
# ============================================================ |
5. 账号文件 /etc/ppp/chap-secrets
# client server secret IP addresses |
格式说明(pppd 兼容格式,列间用空格/Tab):
| 列 | 含义 |
|---|---|
| 1 | 用户名 |
| 2 | 服务器名(仅为兼容标准,写 *) |
| 3 | 密码 |
| 4 | 分配的 IP:* = 从 [ip-pool] 池里取;写固定 IP 则分配固定 IP;也可写池名 |
6. NAT 转发(客户端上外网的关键)
# 1. 开启内核转发 |
ppp+是通配符,匹配所有 pppX 拨号接口;- 双网卡方案把
-o ens33换成上联网卡; - 先验证服务器自己能上网:
ping 223.5.5.5。
7. 启动服务
方式 A:前台(调试推荐)
accel-pppd -c /etc/accel-ppp.conf |
- 前台终端”没输出”是正常的:启动日志走
/var/log/accel-ppp/accel-ppp.log,只有日志模块加载之前的致命错误才打到 stderr; - 另开一个窗口
tail -f /var/log/accel-ppp/accel-ppp.log观察; - Ctrl+C 停止。
方式 B:systemd(常驻)
/etc/systemd/system/accel-ppp.service:
[Unit] |
systemctl daemon-reload |
⚠️ 最重要的规矩:只能有一个实例
systemd 起了一个、又手动起一个 = 同一二层出现两个 PPPoE 服务器,客户端必报 incorrect AC-Cookie(见踩坑 2)。启动前先确认干净:
pkill -f accel-pppd ; sleep 1 ; pgrep -af accel-pppd # 应无输出 |
8. Windows 客户端拨号
图形界面:
设置 → 网络和 Internet → 拨号 → 设置新连接(或控制面板 → 网络和共享中心 → 设置新的连接或网络 → 连接到 Internet)- 选 宽带 (PPPoE)
- 输入
user1/pass123→ 连接
命令行方式:
rasdial "宽带连接" user1 pass123 |
9. 验证(三层递进)
服务器侧:
tail -f /var/log/accel-ppp/accel-ppp.log |
客户端侧(逐层定位,哪层断修哪层):
ipconfig /all |
10. 踩坑实录(本次实战的真实故障,按时间线)
坑 1:ccp: failed to get flags: Bad file descriptor
error: ens33: ccp: failed to get flags: Bad file descriptor |
结论:无害噪音——会话拆除瞬间 CCP 还在尝试读 socket。[ppp] 加 ccp=0、mppe=deny 后不再出现。不要被它带偏,它不是掉线原因。
坑 2:discard PADR packet (incorrect AC-Cookie)
现象:客户端反复拨不上。日志显示 PADO 发出的 AC-Cookie 与 PADR 带回来的对不上。
原因:同一二层里跑了两个 accel-pppd 实例(systemd 起了一个,前台又手动起了一个)。PADI 广播被两个实例同时应答,客户端把 A 实例的 cookie 通过 PADR 发给了 B 实例。
解决:pkill -f accel-pppd,只留一个实例。
教训:同一 L2 只能有一个 PPPoE 服务实例;用 systemd 就别再手动起。
坑 3:认证层空转 → 38 秒后客户端超时拆链
现象:PADS 成功(sid=0001)、LCP 协商完成、auth_layer_start 之后两边都没动静,客户端等 38 秒发 LCP TermReq 掉线。
原因:[modules] 里只写了 chap-secrets(账号存哪),没写 auth_pap 等认证协议模块 → 服务器在 LCP 里根本不提出”要认证”,Windows 干等。
解决:补 auth_pap / auth_chap_md5 / auth_mschap_v1 / auth_mschap_v2。
教训:chap-secrets 是”密码本”,auth_* 才是”验密码的协议”,两类都要加载。
坑 4:no free IPv4 address
recv [IPCP ConfReq <addr 0.0.0.0> ...] |
现象:认证成功后客户端要 IP,服务器说没地址,直接把 IPCP(协议号 0x8021)拒绝并拆链。
原因:配置段写成了 [ippool],而这个版本源码只认 [ip-pool](accel-pppd/extra/ippool.c:450 → conf_get_section("ip-pool")),地址池等于没配。
解决:
sed -i 's/^\[ippool\]$/[ip-pool]/' /etc/accel-ppp.conf |
教训:模块名 ≠ 配置段名。[modules] 里写 ippool,配置段必须叫 [ip-pool]。拿不准时去源码里搜 conf_get_section(),那才是真名。
坑 5:能连上、ping 公网 IP 通,ping 域名不通
ping 10.10.10.1 ✓(隧道) |
原因:试图在 [ip-pool] 里用 attr-dns1= / attr-dns2= 下发 DNS,但当前版本解析 [ip-pool] 时只认 gw-ip-address / shuffle / reload-orphan / gw / tunnel / 裸地址段,未知键直接 continue 静默忽略。DNS 的真正读取点在 accel-pppd/ppp/ipcp_opt_dns.c:167/171 → conf_get_opt("dns", "dns1"/"dns2")。
解决:删掉 attr-dns1/attr-dns2 两行,新增 [dns] 段(见第 4 章)。
教训:配置项放错段 = 静默失效,不会报任何错。accel-ppp 对无法识别的键一律跳过。
11. 日常运维命令
# 日志 |
12. 故障速查表
| 现象 / Windows 错误码 | 原因 | 处理 |
|---|---|---|
discard PADR (incorrect AC-Cookie) |
二层里有两个服务实例 | pkill -f accel-pppd 只留一个 |
| 拨号后 30~40 秒掉线、日志无认证报文(错误 691) | [modules] 缺 auth_* 协议模块 |
补 4 个 auth 模块 |
no free IPv4 address(错误 734/738) |
地址池段名或格式错 | 段名必须 [ip-pool],池内写裸地址段 |
| ping 公网 IP 通、ping 域名不通 | DNS 未下发 | [dns] 段;删 [ip-pool] 里无效的 attr-dns |
ping 10.10.10.1 都不通(错误 651) |
二层不通 / 监听网卡错 | 两 VM 同一 VMnet;interface= 写对网卡 |
| ping 公网 IP 也不通 | NAT / 转发没开 | ip_forward=1 + MASQUERADE + FORWARD 放行 |
| 认证失败(错误 691) | 账号密码错 / 协议不匹配 | 查 /etc/ppp/chap-secrets 与 auth-fail.log |
can't load module xxx |
模块文件不在搜索路径 | ls /usr/lib64/accel-ppp/ 确认 |
| 服务器前台”没输出” | 正常现象 | 日志在 /var/log/accel-ppp/accel-ppp.log |
13. 附录:纯净版配置(可直接粘贴)
/etc/accel-ppp.conf:
[modules] |
/etc/ppp/chap-secrets:
user1 * pass123 * |
启动清单:
mkdir -p /var/log/accel-ppp |
源码引用基于官方 master(本环境编译版本 c9d9381):accel-pppd/extra/ippool.c:450、accel-pppd/ppp/ipcp_opt_dns.c:167。
