本文详细记录如何在 Debian 13 (Trixie) + Linux Kernel 6.12 环境下,从零编译部署全功能 Accel-PPP,配置 SSTP VPN 服务器,并实现 IPv4 + IPv6 双栈 完整支持。
核心目标
- 更换标准内核(云服务器默认内核缺少 PPP 模块)
- 编译全功能 Accel-PPP
- 手动修复内核驱动
- 配置网络转发与 NAT
- 实现 IPv6 完整支持
第一阶段:更换标准内核
云服务器默认的 cloud 内核缺少必要模块,必须更换。
安装标准内核与头文件
sudo apt updatesudo apt install linux-image-amd64 linux-headers-amd64更新引导并重启
sudo update-grubsudo reboot检查内核 PPP 模块
重启后,确保所有基础 PPP 模块均可加载:
# 加载内核 ppp 模块sudo modprobe ppp_genericsudo modprobe ppp_asyncsudo modprobe ppp_mppesudo modprobe ip_gre
# 验证(应有输出且无报错)lsmod | grep ppp第二阶段:安装编译依赖
注意:Debian 13 需使用
libpcre2-dev(旧版 pcre3 已废弃)。
sudo apt updatesudo apt install build-essential cmake git gcc \ linux-headers-$(uname -r) \ libpcre2-dev libssl-dev liblua5.1-0-dev \ libnl-3-dev libnl-genl-3-dev libsnmp-dev \ libpq-dev libpcap-dev第三阶段:下载与编译
开启所有高级特性(Radius, SNMP, Shaper, Lua, IPoE Driver)。
获取源码
cd /usr/srcrm -rf accel-ppp # 删除旧目录git clone https://github.com/accel-ppp/accel-ppp.gitcd accel-pppmkdir buildcd build配置 CMake
cmake -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_BUILD_TYPE=Release \ -DLOG_PGSQL=TRUE \ -DSHAPER=TRUE \ -DRADIUS=TRUE \ -DNETSNMP=TRUE \ -DLUA=TRUE \ -DBUILD_IPOE_DRIVER=TRUE \ -DBUILD_VLAN_MON_DRIVER=TRUE \ -DKDIR=/usr/src/linux-headers-$(uname -r) \ ..编译
make忽略 OpenSSL deprecated 警告,只要最后显示
[100%] Built target ...即成功。
第四阶段:安装与驱动修复
由于新内核路径差异,必须手动归位 .ko 驱动文件。
基础安装
sudo make install手动复制内核驱动
# 创建系统模块目录sudo mkdir -p /lib/modules/$(uname -r)/extra/accel-ppp
# 查找编译好的驱动并复制find . -name "ipoe.ko" -exec sudo cp {} /lib/modules/$(uname -r)/extra/accel-ppp/ \;find . -name "vlan_mon.ko" -exec sudo cp {} /lib/modules/$(uname -r)/extra/accel-ppp/ \;刷新并加载驱动
# 更新模块依赖sudo depmod -a
# 加载驱动sudo modprobe ipoesudo modprobe vlan_mon
# 验证(必须看到 ipoe 和 vlan_mon)lsmod | grep -E 'ipoe|vlan_mon'检查已安装的模块
ls /usr/lib64/accel-ppp/关键 IPv6 模块确认(必须存在):
libipv6pool.so- IPv6 地址池libipv6_nd.so- Router Advertisement(关键!)libipv6_dhcp.so- DHCPv6(可选)
第五阶段:配置网络转发与 NAT
⚠️ 注意:将命令中的
eth0替换为你服务器真实的公网接口名称(用ip addr查看)。
开启内核转发
# 开启转发sysctl -w net.ipv4.ip_forward=1sysctl -w net.ipv6.conf.all.forwarding=1
# 持久化配置cat >> /etc/sysctl.conf << EOFnet.ipv4.ip_forward=1net.ipv6.conf.all.forwarding=1EOF
sysctl -p方案一:手动配置 NAT 规则
适合需要持久化规则或与其他服务共用的场景。
配置 IPv4 NAT
iptables -P FORWARD ACCEPTiptables -t nat -A POSTROUTING -s 192.168.200.0/24 -o eth0 -j MASQUERADE配置 IPv6 NAT
ip6tables -P FORWARD ACCEPTip6tables -t nat -A POSTROUTING -s fd00::/48 -o eth0 -j MASQUERADE持久化 iptables 规则(可选)
如果希望规则在重启后保留:
apt install iptables-persistentnetfilter-persistent save内核升级注意事项
⚠️ 重要:升级内核(如从 Debian 13 升级到 Debian 14)后,需要执行以下操作:
| 组件 | 升级后影响 | 需要操作 |
|---|---|---|
ipoe.ko / vlan_mon.ko | ❌ 不兼容新内核 | 需要重新编译 |
| PPP 内核模块 | ✅ 通常保持 | 重新 modprobe |
| accel-pppd 主程序 | ✅ 通常不受影响 | 无需操作 |
| 配置文件 | ✅ 不受影响 | 无需操作 |
内核升级后重新编译步骤:
# 1. 安装新内核头文件apt install linux-headers-$(uname -r)
# 2. 重新编译cd /usr/src/accel-ppp/buildcmake -DKDIR=/usr/src/linux-headers-$(uname -r) ..make clean && make
# 3. 重新安装驱动make installmkdir -p /lib/modules/$(uname -r)/extra/accel-pppfind . -name "*.ko" -exec cp {} /lib/modules/$(uname -r)/extra/accel-ppp/ \;depmod -a
# 4. 重启服务systemctl restart accel-ppp💡 提示:如果只使用 SSTP 协议(不用 IPoE/PPPoE),
ipoe.ko和vlan_mon.ko驱动可能非必需,服务仍可正常运行。
方案二:使用启动脚本(推荐)
优点:启动时自动添加规则,停止时自动清理,不影响其他 iptables 规则。
📌 注意:此脚本依赖配置文件
/opt/accel-ppp/accel-ppp.conf,该文件在第六阶段创建。请先完成后续配置再使用此脚本。
创建 /opt/accel-ppp/start.sh:
#!/bin/bash## Accel-PPP SSTP VPN 启动脚本# 启动时添加 NAT 规则,退出时自动清理#
# ===== 配置区域(请根据实际情况修改)=====ACCEL_CONF="/opt/accel-ppp/accel-ppp.conf"INTERFACE="eth0" # 替换为你的公网网卡IPV4_SUBNET="192.168.200.0/24"IPV6_SUBNET="fd00::/48"# =========================================
RED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 添加 NAT 规则add_rules() { log_info "添加 IPv4 NAT 规则..." iptables -t nat -C POSTROUTING -s "$IPV4_SUBNET" -o "$INTERFACE" -j MASQUERADE 2>/dev/null || \ iptables -t nat -A POSTROUTING -s "$IPV4_SUBNET" -o "$INTERFACE" -j MASQUERADE
log_info "添加 IPv6 NAT 规则..." ip6tables -t nat -C POSTROUTING -s "$IPV6_SUBNET" -o "$INTERFACE" -j MASQUERADE 2>/dev/null || \ ip6tables -t nat -A POSTROUTING -s "$IPV6_SUBNET" -o "$INTERFACE" -j MASQUERADE
log_info "NAT 规则已添加"}
# 删除 NAT 规则(只删除我们添加的,不影响其他规则)remove_rules() { echo "" log_info "清理 IPv4 NAT 规则..." iptables -t nat -D POSTROUTING -s "$IPV4_SUBNET" -o "$INTERFACE" -j MASQUERADE 2>/dev/null && \ log_info "IPv4 NAT 规则已移除" || log_warn "IPv4 NAT 规则不存在或已移除"
log_info "清理 IPv6 NAT 规则..." ip6tables -t nat -D POSTROUTING -s "$IPV6_SUBNET" -o "$INTERFACE" -j MASQUERADE 2>/dev/null && \ log_info "IPv6 NAT 规则已移除" || log_warn "IPv6 NAT 规则不存在或已移除"
log_info "清理完成"}
# 清理函数(捕获退出信号时调用)cleanup() { log_warn "收到退出信号,正在停止服务..." [ -n "$ACCEL_PID" ] && kill "$ACCEL_PID" 2>/dev/null && wait "$ACCEL_PID" 2>/dev/null remove_rules log_info "Accel-PPP 已停止" exit 0}
# 检查 root 权限[ "$EUID" -ne 0 ] && { log_error "请使用 root 权限运行"; exit 1; }
# 检查配置文件和网卡[ ! -f "$ACCEL_CONF" ] && { log_error "配置文件不存在: $ACCEL_CONF"; exit 1; }ip link show "$INTERFACE" &>/dev/null || { log_error "网卡不存在: $INTERFACE"; exit 1; }
# 捕获退出信号trap cleanup SIGINT SIGTERM SIGHUP EXIT
# 确保内核转发已开启log_info "检查内核转发设置..."sysctl -w net.ipv4.ip_forward=1 >/dev/nullsysctl -w net.ipv6.conf.all.forwarding=1 >/dev/null
# 添加 NAT 规则add_rules
# 启动 accel-pppdlog_info "启动 Accel-PPP..."log_info "配置文件: $ACCEL_CONF"log_info "按 Ctrl+C 停止服务并清理规则"echo ""
accel-pppd -c "$ACCEL_CONF" &ACCEL_PID=$!
wait "$ACCEL_PID"使用方法
# 添加执行权限chmod +x /opt/accel-ppp/start.sh
# 启动(前台运行,Ctrl+C 停止并自动清理规则)/opt/accel-ppp/start.sh验证规则
# 查看当前 NAT 规则iptables -t nat -L POSTROUTING -n -vip6tables -t nat -L POSTROUTING -n -v第六阶段:SSTP + IPv6 完整配置
这是经过验证的、支持 IPv4 + IPv6 双栈 的 SSTP VPN 配置。
创建账户文件
mkdir -p /opt/accel-pppnano /opt/accel-ppp/account格式(每行一个用户):
username * password *创建完整配置文件
创建 /opt/accel-ppp/accel-ppp.conf:
[modules]sstpauth_mschap_v2ippoolipv6poolipv6_nd# ipv6_dhcp # 一般不需要chap-secrets
[core]thread-count=2log-error=/dev/stderr
[common]
[chap-secrets]chap-secrets=/opt/accel-ppp/accountencrypted=0
[ppp]verbose=1ipv4=requireipv6=requireipv6-intf-id=randomipv6-peer-intf-id=randommppe=require
[sstp]verbose=1bind=::0port=8443accept=sslssl-ciphers=DEFAULTssl-protocol=tls1.2,tls1.3ssl-pemfile=/path/to/fullchain.pemssl-keyfile=/path/to/privkey.pemhost-name=your.domain.comip-pool=sstpipv6-pool=sstp-v6ifname=sstp%d
[dns]dns1=1.1.1.1dns2=8.8.8.8
# (可选) IPv6 DNS 用的是dns而不是dns1/dns2[ipv6-dns]dns=2606:4700:4700::1111dns=2001:4860:4860::8888
[client-ip-range]192.168.200.100-192.168.200.254
[ip-pool]gw-ip-address=192.168.200.1attr=Framed-Pool192.168.200.3-254,name=sstp
[ipv6-pool]fd00::/48,64,name=sstp-v6
[ipv6-nd]verbose=1# 加快初始 RA 发送MaxInitialRtrAdvCount=10MaxInitialRtrAdvInterval=1# 缩短 RA 间隔(对 iOS 可能有帮助)MaxRtrAdvInterval=60MinRtrAdvInterval=20
# 需要时再启用# [ipv6-dhcp]# verbose=1# pref-lifetime=604800# valid-lifetime=2592000
[log]log-file=/dev/stderrlog-emerg=/dev/stderrlog-fail-file=/dev/stderrcopy=1level=3
[cli]verbose=1telnet=127.0.0.1:2000tcp=127.0.0.1:2001第七阶段:IPv6 配置详解
为什么 Windows 只获取 fe80 地址?
PPP 协议的 IPv6CP 只协商 Interface ID,不分配完整的 IPv6 地址。客户端获取全局 IPv6 地址需要:
| 方式 | 模块 | 说明 |
|---|---|---|
| SLAAC | ipv6_nd | 发送 Router Advertisement,客户端自动配置地址 |
| DHCPv6 | ipv6_dhcp | 通过 DHCPv6 协议分配地址 |
Windows 客户端依赖 Router Advertisement (RA),因此 ipv6_nd 模块是必须的!
关键配置项解析
[modules]ipv6pool # IPv6 地址池管理ipv6_nd # ⭐ 关键!发送 Router Advertisementipv6_dhcp # DHCPv6 支持(推荐同时启用)
[ppp]ipv6=require # 强制要求 IPv6ipv6-intf-id=random # 服务器端接口 ID 随机生成ipv6-peer-intf-id=random # 客户端接口 ID 随机生成
[ipv6-pool]# 格式:前缀/总长度,分配长度,name=池名称fd00::/48,64,name=sstp-v6# 表示:从 fd00::/48 中,给每个客户端分配一个 /64 子网
[ipv6-nd]verbose=1 # 启用 RA 详细日志常见错误
| 错误配置 | 问题 |
|---|---|
只用 ipv6pool 不用 ipv6_nd | Windows 只能获取 fe80 地址 |
使用 delegate=1 | 这是给路由器的前缀委派,终端设备不支持 |
| ip6tables NAT 前缀与 ipv6-pool 不匹配 | IPv6 无法上网 |
第八阶段:启动与验证
启动服务
# 前台运行(用于调试)accel-pppd -c /opt/accel-ppp/accel-ppp.conf
# 后台运行accel-pppd -c /opt/accel-ppp/accel-ppp.conf -d验证 IPv6 工作
服务器端检查:
ip -6 addr show | grep sstpWindows 客户端检查:
ipconfig /all# 应该看到:# IPv6 地址: fd00:xxxx::xxxx# 链路本地 IPv6 地址: fe80::xxxx测试 IPv6 连通性:
ping -6 ipv6.google.comCLI 管理
telnet 127.0.0.1 2000
# 常用命令show sessions # 查看当前会话show stat # 查看统计信息terminate sid xxx # 断开指定会话第九阶段:创建 Systemd 服务
创建服务文件
nano /etc/systemd/system/accel-ppp.service[Unit]Description=Accel-PPP VPN ServerAfter=network.target
[Service]Type=forkingExecStart=/usr/sbin/accel-pppd -c /opt/accel-ppp/accel-ppp.conf -dExecReload=/bin/kill -HUP $MAINPIDRestart=on-failureRestartSec=5
[Install]WantedBy=multi-user.target启用服务
systemctl daemon-reloadsystemctl enable accel-pppsystemctl start accel-pppsystemctl status accel-ppp故障排查
IPv6 不工作检查清单
| 检查项 | 命令 |
|---|---|
| 模块是否存在 | ls /usr/lib64/accel-ppp/ | grep ipv6 |
| 内核转发是否开启 | sysctl net.ipv6.conf.all.forwarding |
| ip6tables NAT 规则 | ip6tables -t nat -L -n |
| 服务器接口 IPv6 | ip -6 addr show |
日志调试
journalctl -u accel-ppp -fWindows 客户端优化
禁用智能多宿主 DNS 解析
Windows 默认启用的「智能多宿主名称解析」会向所有网络接口的 DNS 服务器并行发送查询,这会导致 DNS 请求绕过 VPN 隧道,造成泄露。
推荐操作:连接 SSTP VPN 前,禁用此功能:
- 组策略(Pro/Enterprise):
gpedit.msc→ 计算机配置 → 管理模板 → 网络 → DNS 客户端 → 启用「禁用智能多宿主名称解析」 - 注册表(所有版本):
Terminal window reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" /v "EnableMulticast" /t REG_DWORD /d 0 /f
总结
✅ 关键点回顾:
- 必须加载
ipv6_nd模块发送 Router Advertisement ipv6_dhcp模块推荐同时启用- IPv6 pool 配置格式:
前缀/总长度,分配长度,name=池名称 - NAT 规则前缀必须与 ipv6-pool 匹配
⚠️ 注意事项:
- 云内核需更换为标准内核
- 驱动文件需手动复制到正确位置
- 修改配置后需重启服务