Unix Like, VPN, 操作系统, 服务器

一款鲜为人知的杰出VPN方案 —— ACCEL-PPP

因PPTP简单、方便,无特别需要,平时需要用到VPN时一般都会首选PPTP。

数月前使用PPTP的过程中发现,Linux下的PoPToP方案极限速率仅有20 Mbps左右,而Windows下“网络策略和访问服务”提供的PPTP上限速率则高些,能达到70 – 80 Mbps。

当时了解到一款名为ACCEL-PPP的方案,尝试了一番,效果不负其名——ACCEL。

但今天发现,此方案的中文介绍、资料近乎无(英文介绍也不多),遂撰写此文,欲让更多人了解到此杰作。

 

服务器配置:

  • CPU: Intel Xeon L5520 *2
  • RAM: 48GB
  • 网络适配器: Intel 千兆网络适配器
  • 硬盘: 256GB SSD

 

网络环境:

  • ISP: 中国电信
  • 公网速率: 100 Mbps
  • 路由器: EdgeRouter X SFP (with hwnat, ipsec offload enable)

 

本文部分词语定义:

极限速率 —— 当数据传输速率在30秒内不能稳定提升,则视当前已达极限速率

 

PoPToP

PoPToP就是Linux更新源所提供的的pptpd。

达到极限速率后,使用top看到服务器上pptpd进程的CPU使用率仅有25-30%:

图1 —— PoPToP极限速率
图2 —— pptpd进程CPU使用率1
图3 —— pptpd进程CPU使用率2

速率已达极限,而资源使用却未达极限,明显问题在于PoPToP方案的资源利用率底下。

ACCEL-PPP PPTP

图4 —— ACCEL-PPP PPTP极限速率
图5 —— ACCEL-PPP PPTP CPU使用率

ACCEL-PPP的PPTP极限速率能达到50 Mbps多,使用top查看CPU使用率,可以发现大部分都被ksoftirqd占用,且使用率几乎可达一个核心的极限。

虽然未能达到我公网带宽的极限速率,但能充分利用资源达到如此高的速率已经很不错了。

ACCEL-PPP的文档没对其工作原理作出介绍,我也未深究其源码,暂不能解释其“高效”、以及受限于其“极限”的原因。

ACCEL-PPP L2TP与xl2tpd的性能对比

使用StrongSwan,IPSec PSK

xl2tpd

图6 —— xl2tpd效率1
图7 —— xl2tpd效率2

ACCEL-PPP L2TP

图8 —— ACCEL-PPP L2TP效率1
图9 —— ACCEL-PPP效率2

孰优孰劣,明显至极。

ACCEL-PPP的安装

本节以Debian 9为例,安装ACCEL-PPP。

安装编译器,cmake:

apt-get install build-essential cmake

取得ACCEL-PPP源码(编写本文时,SourceForge的ACCEL-PPP 1.11.2的源码扩展名虽为.tar.bz2,但实际上只由tar打包,并无使用bzip压缩)

ACCEL_PPP_VERSION="1.11.2"
wget -O- "https://sourceforge.net/projects/accel-ppp/files/accel-ppp-${ACCEL_PPP_VERSION}.tar.bz2/download" | tar -xvf-

编译ACCEL-PPP:

ACCEL-PPP编译前需要使用cmake对所需的功能进行设置,支持的选项有以下:

  • -DBUILD_PPTP_DRIVER=TRUE —— 本选项用于编译PPTP内核模块,内核版本>= 2.6.37已内置PPTP模块,无需启用该选项。
  • -DBUILD_IPOE_DRIVER=TRUE —— 本选项用于编译IPoE内核模块。IPoE共享接口模式或VLAN监控下需要此模块。
  • -DBUILD_VLAN_MON_DRIVER=TRUE —— 编译VLAN监控模块。
  • -DKDIR=/usr/src/linux —— 若需要构建PPTP内核模块,则需要使用本选项指定内核源码目录。
  • -DCMAKE_INSTALL_PREFIX=/some/location —— 指定ACCEL-PPP安装目录,默认为/usr/local。
  • -DCMAKE_BUILD_TYPE=Debug —— 选择编译为DEBUG版本以用于调试抑或为RELEASE版本。
  • -DLOG_PGSQL=TRUE —— 编译log_pgsql模块用于使用PostreSQL数据库记录日志。
  • -DRADIUS=FALSE —— 关闭radius模块。
  • -DNETSNMP=TRUE —— 启用SNMP模块。
  • -DLUA=TRUE —— 启用LUA支持(仅用于IPoE)。
  • -DSHAPE=TRUE —— 启用流量控制功能。

本文编译为Release版本,关闭Radius,PGSQL,流量控制等功能。

mkdir accel-ppp-${ACCEL_PPP_VERSION}/build
pushd accel-ppp-${ACCEL_PPP_VERSION}/build

BUILD_JOBS=8
cmake \
-DBUILD_DRIVER=false \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_BUILD_TYPE=Release \
-DLOG_PGSQL=FALSE \
-DSHAPER=FALSE \
-DRADIUS=false \
-DNETSNMP=FALSE \
..
make -j${BUILD_JOBS}
make -j${BUILD_JOBS} install

popd

重命名配置文件:

mv /etc/accel-ppp.conf.dist /etc/accel-ppp.conf

ACCEL-PPP的配置

从man可获取到accel-ppp配置文件的完整文档:

man accel-ppp.conf

本小节仅对部分配置项进行说明。

[modules]

本部分定义了ACCEL-PPP需要启用的功能。

例如

log_file

pptp
l2tp

auth_mschap_v2
auth_mschap_v1
auth_chap_md5
auth_pap

chap-secrets

ippool

pppd_compat

则表示启用文件日志,pptp,l2tp等功能。

[core]

用于配置核心模块的参数。

当前版本支持的有以下两项:

       log-error=path
              错误日志文件路径

       thread-count=n
              工作线程数

[ppp]

ACCEL-PPP内置的ppp模块参数配置。

具体略。

[dns]

dns1=x.x.x.x
    首选DNS服务器
dns2=x.x.x.x
    备选DNS服务器

[client-ip-range]

设置允许连接本服务器的客户IP,格式:
    x.x.x.x/mask (如:10.0.0.0/8)
    x.x.x.x-y (如:10.0.0.1-254)

[pptp]

       配置PPTP模块参数

       bind=x.x.x.x
              PPTP服务器所监听的IP地址

       port=n
              指定PPTP服务器端口

       verbose=n
              如果n大于0,PPTP模块将会启用日志

       echo-interval=n
              如果n大于0,PPTP模块会每n秒发送一个echo-request

       echo-failure=n
              n个echo-request请求未收到echo-reply后,中断连接

       timeout=n
              等待客户端回应,n秒后无回应视为超时(默认为5秒)

       mppe=deny|allow|prefer|require

[l2tp]

       配置L2TP模块

       bind=x.x.x.x

       port=n

       host-name=string
              给客户端发送的Host-Name属性

       hello-interval=n
              指定发送Hello控制消息的周期。用于keep alive连接,如果peer无回应,中断连接。

       recv-window=n
              设置本地receive window的大小。只有sequence number在[last-Nr + 1, last-Nr + recv-window]范围内才会被接收(last-Nr是最后一次消息的sequence number)。最小值为1,最大值为32768,默认为16。

       timeout=n
              指定等待客户端completes tunnel and session negotiation的超时时间(单位:秒)

       rtimeout=n
              指定等待确认收到消息的时间(单位秒),丢包后将会重发。每次重发,超时值都会x2.
              如果rtimeout被设为1,第一次重发将会在1秒后,第二次重发将会在2秒后,以此类推,直到收到回应或到达retransmit值。
              n默认为1。

       rtimeout-cap=n
              最长重发时间,rtimeout的增长不会超过此值。
              必须大于rtimeout,根据RFC 2661,一定不能小于8(accel-ppp没有此限制)。
              默认为16。

       retransmit=n
              指定最大的重发次数

       verbose=n
              n >= 0,将会启用日志

       mppe=deny|allow|prefer|require

       secret=string
              设置密钥

       hide-avps=n
              n >= 0,接收到的L2TP数据包属性将会隐藏(AVPs支持)

[chap-secrets]

       配置chap-secrets模块

       gw-ip-address=x.x.x.x[/mask]
              当启用chap-secrets分配IP时,指定ppp接口使用的本地IP。Mask用于IPoE。

       chap-secrets=file
              设置chap-secrets文件路径(默认为/etc/ppp/chap-secrets)

       encrypted=0|1
              chap-secrets是否已加密(见README)

       username-hash=hash1[,hash2]
              指定计算用户名hash值的hash链。
              hash1,hash2是openssl所支持的hash算法(如md5,sha1等)。

[ip-pool]

       配置ippool模块

       gw-ip-address=x.x.x.x
              指定ppp接口所使用的本地地址

       shuffle=1|0
              Specifies whether to shuffle initial address list. # 我不太了解本选项的功能,可能是不按顺序给客户端分配IP。

       gw=range
              设置本地ppp接口的IP范围,格式:
              x.x.x.x/mask[,name=pool_name] (如:10.0.0.0/8)
              x.x.x.x-y[,name=pool_name] (如:10.0.0.1-254)

       tunnel=range
              指定ppp接口的远程地址范围,格式:
              x.x.x.x/mask[,name=pool_name]
              x.x.x.x-y[,name=pool_name]

       x.x.x.x/mask[,name=pool_name] or x.x.x.x-y[,name=pool_name]
              同样用于指定ppp接口远程地址范围.

示例配置文件

[modules]
log_file
pptp
auth_mschap_v2
auth_mschap_v1
auth_chap_md5
auth_pap
chap-secrets
ippool
pppd_compat

[core]
log-error=/var/log/accel-ppp/core.log
thread-count=4

[ppp]
verbose=1
min-mtu=1280
mtu=1400
mru=1400
mppe=require
ipv4=require
ipv6=deny
ipv6-intf-id=0:0:0:1
ipv6-peer-intf-id=0:0:0:2
ipv6-accept-peer-intf-id=1
lcp-echo-interval=20
lcp-echo-timeout=120
unit-cache=1

[pptp]
verbose=1
ip-pool=pool1

[l2tp]
verbose=1
dictionary=/usr/local/share/accel-ppp/l2tp/dictionary
hello-interval=60
ip-pool=pool2

[dns]
dns1=8.8.8.8
dns2=8.8.4.4

[client-ip-range]
0.0.0.0/0

[ip-pool]
gw-ip-address=10.1.1.1
10.10.2.2-254,name=pool1
10.1.1.2-254,name=pool2

[log]
log-file=/var/log/accel-ppp/accel-ppp.log
log-emerg=/var/log/accel-ppp/emerg.log
log-fail-file=/var/log/accel-ppp/auth-fail.log
copy=1
level=3

[pppd-compat]
ip-up=/etc/ppp/ip-up
ip-down=/etc/ppp/ip-down
ip-change=/etc/ppp/ip-change
radattr-prefix=/var/run/radattr
verbose=1

[chap-secrets]
chap-secrets=/etc/ppp/chap-secrets

[cli]
verbose=1
telnet=127.0.0.1:2000
tcp=127.0.0.1:2001

[accel-dp]
socket=/var/run/accel-dp.sock

运行并使用ACCEL-PPP

# -d参数用于运行为Daemon模式
# -c参数指定配置文件路径
/usr/local/sbin/accel-pppd -d -c /etc/accel-ppp.conf

客户端的使用方式与平常无差异,使用IPSec的,按照正常方式对IPSec进行配置即可。

总结

ACCEL-PPP网站有有言:

ACCEL-PPP是一个高性能的Linux VPN服务器应用。

致力于聚合各种热门的VPN技术。

单VPN上,对比如今广泛使用的PoPToP与xl2tp,ACCEL-PPP的优势非常明显,但如此杰作却鲜为人知,实为作者感到不平。

若你尝试ACCEL-PPP后,觉得好用,记得推荐给你身边的朋友!

ACCEL-PPP官网:http://accel-ppp.org/

SourceForge项目:https://sourceforge.net/projects/accel-ppp/

社区:http://accel-ppp.org/forum/

102 Posts

自信、努力、活出精彩;以前未所见的颜色,绘大千世界!
View all posts

11 thoughts on “一款鲜为人知的杰出VPN方案 —— ACCEL-PPP”

  1. 请问下,如果要给openwrt编译accel-pptp应该注意什么?会不会与自带的pppd冲突?谢谢!

      1. 感谢回复,我看到你在编译RELEASE版本的时候没有选择编译IPoE和VLANMon模块,是否是在使用VPN的条件下不需要这两个模块呢?谢谢!

          1. 在GitHub上找了个看起来适用于openwrt的makefile,结果编译完了之后用不了,先是undefined symbol,Google了一下又试着加了target_linking_libraries,这回是relocating failed,给报错的几个so创建了链接吧,直接就segfault闪退了……

  2. 我又来了。补充一个systemd 的脚本

    vim /etc/systemd/system/accel-ppp.service

    [Unit]
    Description=Accel-PPP
    After=network.target

    [Service]
    ExecStart=/usr/local/sbin/accel-pppd -d -p /var/run/accel-pppd.pid -c /etc/accel-ppp.conf
    StandardOutput=null
    ExecReload=/bin/kill -SIGUSR1 $MAINPID
    PIDFile=/var/run/accel-pppd.pid
    Type=forking
    Restart=always

    [Install]
    WantedBy=multi-user.target
    Alias=accel-ppp.service

  3. 文章有一些错误。。
    比如编译的时候 先Mkdir 一个目录 进去滞后在cmake 配置
    然后才能使用 “..” 这样来表示上一级目录 也就是

    ACCEL_PPP_VERSION=”1.11.2″
    wget -O- “https://sourceforge.net/projects/accel-ppp/files/accel-ppp-${ACCEL_PPP_VERSION}.tar.bz2/download” | tar -xvf-
    mkdir -p accel-ppp-${ACCEL_PPP_VERSION}/build
    cd accel-ppp-${ACCEL_PPP_VERSION}/build

    cmake -DBUILD_DRIVER=FALSE -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DLOG_PGSQL=FALSE -DSHAPER=TRUE -DNETSNMP=FALSE -DRADIUS=TRUE ..

    make && makr install

Leave a reply

Your email address will not be published. Required fields are marked *