服务端

安装环境:DigitalOcean
系统:CentOS 7 x64

前言

本配置过程依赖于脚本而来,脚本执行后不成功,故手动分步执行,比较容易找到错误并且修正

安装依赖的组件

yum -y update
yum install -y openswan ppp xl2tpd wget

创建ipsec.conf配置文件

rm -f /etc/ipsec.conf
nano /etc/ipsec.conf

输入以下内容,并替换$serverip为你的服务器ip地址,然后删掉注释内容。
完成后ctrl+o回车保存,ctrl+x退出

# /etc/ipsec.conf - Libreswan IPsec configuration file

# This file:  /etc/ipsec.conf
#
# Enable when using this configuration file with openswan instead of libreswan
#version 2
#
# Manual:     ipsec.conf.5

# basic configuration
config setup
    # NAT-TRAVERSAL support, see README.NAT-Traversal
    nat_traversal=yes
    # exclude networks used on server side by adding %v4:!a.b.c.0/24
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
    # OE is now off by default. Uncomment and change to on, to enable.
    oe=off
    # which IPsec stack to use. auto will try netkey, then klips then mast
    protostack=netkey
    force_keepalive=yes
    keep_alive=1800

conn L2TP-PSK-NAT
    rightsubnet=vhost:%priv
    also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    rekey=no
    ikelifetime=8h
    keylife=1h
    type=transport
    left=$serverip //替换为你的IP
    leftid=$serverip //替换为你的IP
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    dpddelay=40
    dpdtimeout=130
    dpdaction=clear

设置预共享密钥配置文件

rm -f /etc/ipsec.secrets
nano /etc/ipsec.secrets

粘贴以下两行内容,其中:
$serverip 替换为你的服务器ip
$mypsk替换为你的psk密钥,之后建立连接时会用到
完成后ctrl+o回车保存,ctrl+x退出

#include /etc/ipsec.d/*.secrets
$serverip %any: PSK "$mypsk"

创建xl2tpd.conf配置文件

mkdir -p /etc/xl2tpd
rm -f /etc/xl2tpd/xl2tpd.conf
nano /etc/xl2tpd/xl2tpd.conf

输入以下内容,并替换$serverip为你的服务器ip地址,然后删掉注释内容。
完成后ctrl+o回车保存,ctrl+x退出

;
; This is a minimal sample xl2tpd configuration file for use
; with L2TP over IPsec.
;
; The idea is to provide an L2TP daemon to which remote Windows L2TP/IPsec
; clients connect. In this example, the internal (protected) network
; is 192.168.1.0/24.  A special IP range within this network is reserved
; for the remote clients: 192.168.1.128/25
; (i.e. 192.168.1.128 ... 192.168.1.254)
;
; The listen-addr parameter can be used if you want to bind the L2TP daemon
; to a specific IP address instead of to all interfaces. For instance,
; you could bind it to the interface of the internal LAN (e.g. 192.168.1.98
; in the example below). Yet another IP address (local ip, e.g. 192.168.1.99)
; will be used by xl2tpd as its address on pppX interfaces.
[global]
; ipsec saref = yes
listen-addr = $serverip //替换为你的IP
auth file = /etc/ppp/chap-secrets
port = 1701
[lns default]
ip range = 10.0.1.10-10.0.1.254
local ip = 10.0.1.1
refuse chap = yes
refuse pap = yes
require authentication = yes
name = L2TPVPN
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

创建options.xl2tpd配置文件

mkdir -p /etc/ppp
rm -f /etc/ppp/options.xl2tpd
nano /etc/ppp/options.xl2tpd

粘贴以下内容,无需修改
完成后ctrl+o回车保存,ctrl+x退出

#require-pap
#require-chap
#require-mschap
ipcp-accept-local
ipcp-accept-remote
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4
mtu 1400
noccp
connect-delay 5000
# To allow authentication against a Windows domain EXAMPLE, and require the
# user to be in a group "VPN Users". Requires the samba-winbind package
# require-mschap-v2
# plugin winbind.so
# ntlm_auth-helper '/usr/bin/ntlm_auth --helper-protocol=ntlm-server-1 --require-membership-of="EXAMPLE\VPN Users"'
# You need to join the domain on the server, for example using samba:
# http://rootmanager.com/ubuntu-ipsec-l2tp-windows-domain-auth/setting-up-openswan-xl2tpd-with-native-windows-clients-lucid.html

创建chap-secrets配置文件,即用户列表及密码

rm -f /etc/ppp/chap-secrets
nano /etc/ppp/chap-secrets

粘贴以下内容,其中:
$username替换为你的用户名,
$password替换为你的密码,
完成后ctrl+o回车保存,ctrl+x退出

# Secrets for authentication using CHAP
# client     server     secret               IP addresses
$username          l2tpd     $password               *

修改系统配置,允许IP转发

将下列语句执行

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.default.rp_filter=0
sysctl -w net.ipv4.conf.$eth.rp_filter=0
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv4.conf.default.send_redirects=0
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.default.accept_redirects=0

然后:
nano /etc/sysctl.conf
将下列语句粘贴至末尾,无需修改
完成后ctrl+o回车保存,ctrl+x退出

net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.$eth.rp_filter = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0

允许防火墙端口

nano /usr/lib/firewalld/services/l2tpd.xml
粘贴以下内容,无需修改
完成后ctrl+o回车保存,ctrl+x退出

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>l2tpd</short>
  <description>L2TP IPSec</description>
  <port protocol="udp" port="500"/>
  <port protocol="udp" port="4500"/>
  <port protocol="udp" port="1701"/>
</service>

重启防火墙

分别执行下列语句

firewall-cmd --permanent --add-service=l2tpd
firewall-cmd --permanent --add-service=ipsec
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload

允许开机启动

systemctl enable ipsec xl2tpd
systemctl restart ipsec xl2tpd

重启服务器

重启服务器

测试ipsec

ipsec verify

问题

此时可能会报诸多错误
比如服务未启动等等,根据错误信息修正错误

最重要的是,可能会出现vpn可以接入,但是不能打开网页
最终找到的问题在于iptables上,centos7的iptables比较怪异,而且直接写入规则并不能保存,最终解决办法只能是自己写一个sh脚本,开机自动执行。

解决办法

nano etc/rc.d/openl2tp.sh
然后复制以下文字,然后保存。

/sbin/iptables -A INPUT -p udp -m policy --dir in --pol ipsec -m udp --dport 1701 -j ACCEPT
/sbin/iptables -A INPUT -p udp -m udp --dport 1701 -j ACCEPT
/sbin/iptables -A INPUT -p udp -m udp --dport 500 -j ACCEPT
/sbin/iptables -A INPUT -p udp -m udp --dport 4500 -j ACCEPT
/sbin/iptables -A INPUT -p esp -j ACCEPT
/sbin/iptables -A INPUT -m policy --dir in --pol ipsec -j ACCEPT
/sbin/iptables -A FORWARD -d 10.0.1.0/24 -j ACCEPT
/sbin/iptables -A FORWARD -s 10.0.1.0/24 -j ACCEPT
/sbin/iptables -A FORWARD -i ppp+ -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -o eth0 -j MASQUERADE

增加运行权限:
chmod +x openl2tp.sh
然后还需要编辑rc.local文件,在末尾加上/etc/rc.d/openiptables.sh
在之后,因为centos7已经不默认使用rc.d作为启动管理,要想使用rc.d
需要给rc.d加上权限
chmod +x /etc/rc.d/rc.local

尾声

重新执行ipsec verify
观察结果,如果没有failed,则基本配置成功,尝试连入服务,测试结果

客户端

Windows

  1. 网络共享中心
  2. 设置连接或网络
  3. 连接到工作区
  4. 创建新连接
  5. 使用我的Internet连接
  6. 填入服务器地址
  7. 输入用户名密码
  8. 点连接,然后点跳过
  9. 在网络与共享中心左侧的更改适配器设置中,右击刚才新建的VPN链接,属性
  10. 在安全选项卡的VPN类型,选择L2TP/IPsec,点击高级设置,选择使用预共享密钥做身份验证,填入服务器配置的psk密码,点击确定
  11. 连接,测试

net-speeder优化速度

说明

作者在其博客说明了该方法的优劣:
这种方式下,直接优点是降低丢包率,直接缺点是耗费双倍流量。一些延伸影响是更容易触发快速恢复逻辑,避免了丢包时窗口缩减过快。一定程度也能提高网络速度。
在一台VPS上测试后发现,未开启时单线程下载、ssh管道速度在十几K级别。开启后可以达到平均300KB+的速度。效果非常明显。但对于不加速就可以跑满带宽的类型来讲(多线程下载),开启后反而由于多出来的无效流量,导致速度减半。所以对于多线程/高速链路,这个方案是不适合的。

安装

安装依赖库
先安装epel源
rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
然后即可使用yum安装:
yum install libnet libpcap libnet-devel libpcap-devel gcc
然后获取net-speeder

wget https://github.com/snooda/net-speeder/archive/master.zip
unzip master.zip
cd net-speeder
chmod +x build.sh
./build.sh

运行

编译完成后,一切顺利就能在当前目录下看到编译的net_speeder文件了.
按照项目说明:
使用方法(需要root权限启动):
参数:./net_speeder 网卡名 加速规则(bpf规则)
最简单用法:# ./net_speeder venet0 "ip"加速所有ip协议数据

这里,Digital Ocean的网卡名是eth0,于是执行
./net_speeder eth0 "ip"
就可以运行了,具体可以使用ifconfig指令查看你的服务器网卡接口
然后复制到/usr/local/目录并设置开机自启动:

mkdir /usr/local/net_speeder/
cp net_speeder /usr/local/net_speeder/net_speeder
echo 'nohup /usr/local/net_speeder/net_speeder eth0 "ip" >/dev/null 2>&1 &' >> /etc/rc.local

该方案对Ikev2的vpn提速效果十分明显,但对Shadowsocks貌似并不显著(网上也有人Shadowsocks有效果的,此问题待进一步研究)。