---
tags: Linux, VPN
---
# Centos7 搭建L2TP+IPsec VPN
> L2TP是一种工业标准的Internet隧道协议,功能大致和PPTP协议类似,比如同样可以对网络数据流进行加密。不过也有不同之处,比如PPTP要求网络为IP网络,L2TP要求面向数据包的点对点连接;PPTP使用单一隧道,L2TP使用多隧道;L2TP提供包头压缩、隧道验证,而PPTP不支持。L2TP本身不提供加密功能, 经常搭配IPsec加密协议一起使用, 可以提供比PPTP更高级别的数据加密。
## 前期准备
检查L2TP需要的环境支持
```bash=
# 查看主机是否支持pptp,返回结果为yes就表示通过
modprobe ppp-compress-18 && echo yes
# 查看是否开启了TUN
# 有的虚拟机主机需要开启,返回结果为cat: /dev/net/tun: File descriptor in bad state或cat: /dev/net/tun: 文件描述符处于错误状态。就表示通过。
cat /dev/net/tun
```
## 安装
需要安装的软件
- ppp: 提供用户名密码验证功能,实现 VPN 的用户账号密码验证 (Centos7.x已经自带)
- libreswan: 提供 IPsec 功能,加密 IP 数据包
- xl2tpd: 提供 VPN 功能,依赖于 ppp 和 libreswan
开始安装
```bash=
# 先更新
yum install update
yum update -y
# 安装EPEL源,因为CentOS7官方源中已经去掉了xl2tpd
yum install -y epel-release
# 安装xl2tpd和libreswan(libreswan用以实现IPSec,原先的openswan已经停止维护)
yum install -y xl2tpd libreswan lsof
#安装iptables防火墙,一般都有自带
yum install iptables
```
## 配置
### xl2tpd
配置文件`/etc/xl2tpd/xl2tpd.conf`
```bash=
;
; 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]
; listen-addr = 172.16.0.12 # 这里我使用了默认配置, 也就是绑定端口到0.0.0.0
;
; requires openswan-2.5.18 or higher - Also does not yet work in combination
; with kernel mode l2tp as present in linux 2.6.23+
ipsec saref = yes
; Use refinfo of 22 if using an SAref kernel patch based on openswan 2.6.35 or
; when using any of the SAref kernel patches for kernels up to 2.6.35.
; saref refinfo = 30
;
; force userspace = yes
;
; debug tunnel = yes
auth file = /etc/ppp/chap-secrets
port = 1701
[lns default]
ip range = 192.168.100.128-192.168.100.254 # 设置的vpn客户端IP地址段
local ip = 192.168.100.1 # 本机分配的vpn IP地址, 保持同一个段
require chap = yes
refuse pap = yes
require authentication = yes
name = LinuxVPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
```
### ppp
配置文件`/etc/ppp/options.xl2tpd`
```bash=
ipcp-accept-local
ipcp-accept-remote
ms-dns 8.8.8.8
ms-dns 8.8.4.4
# ms-dns 192.168.1.1
# ms-dns 192.168.1.3
# ms-wins 192.168.1.2
# ms-wins 192.168.1.4
name l2tpd
noccp
auth
#obsolete: crtscts
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
#obsolete: lock
lock
proxyarp
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
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2 # Windows连接必须设置
persist
logfile /var/log/xl2tpd.log
```
### IPsec
主配置文件`/etc/ipsec.conf`
```bash=
# /etc/ipsec.conf - Libreswan IPsec configuration file
#
# see 'man ipsec.conf' and 'man pluto' for more information
#
# For example configurations and documentation, see https://libreswan.org/wiki/
config setup
protostack=netkey
dumpdir=/var/run/pluto/
# Normally, pluto logs via syslog.
#logfile=/var/log/pluto.log
#
# Do not enable debug options to debug configuration issues!
#
# plutodebug="control parsing"
# plutodebug="all crypt"
# plutodebug=none
#
# NAT-TRAVERSAL support
# exclude networks used on server side by adding %v4:!a.b.c.0/24
# It seems that T-Mobile in the US and Rogers/Fido in Canada are
# using 25/8 as "private" address space on their wireless networks.
# This range has never been announced via BGP (at least up to 2015)
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10
# if it exists, include system wide crypto-policy defaults
# include /etc/crypto-policies/back-ends/libreswan.config
# It is best to add your IPsec connections as separate files in /etc/ipsec.d/
include /etc/ipsec.d/*.conf
```
:::info
- 第一行config setup必须左对齐,即前面不能有空格,否则会报错
- 其他每一行都必须以Tab开头,否则会报错
- 如果安装的是 openswan,可能需要在 config setup 之前添加 version 2.0
:::
在`/etc/ipsec.secrets`中设置PSK密钥
```bash=
# 格式为 服务器IP %any: PSK “预共享密钥”,其中 %any: 和 PSK 之间有空格
[服务器外网IP] %any: PSK "123456abcdefg"
```
接着继续配置服务器, 修改配置文件`/etc/ipsec.d/l2tp-ipsec.conf`
```bash=
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
dpddelay=10
dpdtimeout=20
dpdaction=clear
forceencaps=yes
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=1.14.239.60
leftprotoport=17/1701
right=%any
rightprotoport=17/%any
```
:::info
- conn开头的两行必须左对齐,开头不能有空格,其他每一行必须以Tab缩进
- left 此时也要填服务器的外网IP
:::
### 添加账号密码
配置文件`/etc/ppp/chap-secrets`
```bash=
# Secrets for authentication using CHAP
# client server secret IP addresses
vpntest l2tpd 123456 192.168.100.129
```
这里我习惯性的给用户指定固定IP, 方便管理, 如果你是使用`*`代替, 那就会自动分配指定段的IP地址
### 开启内核转发
配置文件`/etc/sysctl.conf`
```bash=
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
#
# Use '/sbin/sysctl -a' to list all possible parameters.
# Controls IP packet forwarding
net.ipv4.ip_forward = 1 #此处的值改为1,开启内核转发
# Controls source route verification
# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1
# Controls the use of TCP syncookies
# Controls the default maxmimum size of a mesage queue
kernel.msgmnb = 65536
# Controls the maximum size of a message, in bytes
kernel.msgmax = 65536
# Controls the maximum shared segment size, in bytes
kernel.shmmax = 68719476736
# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296
vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time = 120
# see details in https://help.aliyun.com/knowledge_detail/39428.html
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0 #此处的值必须是0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.all.send_redirects = 0 #添加这几行
net.ipv4.conf.default.send_redirects = 0 #添加这几行
net.ipv4.conf.all.log_martians = 0 #添加这几行
net.ipv4.conf.default.log_martians = 0 #添加这几行
net.ipv4.conf.all.accept_redirects = 0 #添加这几行
net.ipv4.conf.default.accept_redirects = 0 #添加这几行
net.ipv4.icmp_ignore_bogus_error_responses = 1 #添加这几行
# see details in https://help.aliyun.com/knowledge_detail/41334.html
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2
```
完了, 重载内核配置
```bash=
sysctl -p
```
### 配置ip转发
```bash=
## ip为服务器内网ip
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j MASQUERADE
## 查看nat配置
iptables -t nat -L -n
```
## 启动
```bash=
## xl2tpd debug 模式, 可以实时查看运行日志
xl2tpd -D
## IPsec状态检验, 如果有[FAILED]就不行, 需要对症解决
ipsec verify
## 启动
systemctl start ipsec
systemctl start xl2tpd
## 查看状态
systemctl status ipsec
systemctl status xl2tpd
## 设置开机启动
systemctl enable ipsec
systemctl enable xl2tpd
```
## Windows客户端配置
1. `windows+r`打开运行,输入`services.msc`,查找`ipsec policy agent`,启用服务
2. 打开注册表,路径`HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters`
- 添加DWORD值(32位)值,名称`ProhibitIpSec`,值为 1
- 由于缺省的 Windows XP L2TP 传输策略不允许不使用 IPSec 加密的 L2TP 传输,修改`AllowL2TPWeakCrypto`的值为`1`
- 重启电脑
## Linux客户端配置
> 以Centos 7为例
1. 安装 VPN 客户端
```bash=
yum -y install epel-release
yum -y install strongswan xl2tpd
## 设置 VPN 变量
VPN_SERVER_IP='VPN服务器IP'
VPN_IPSEC_PSK='PSK密钥'
VPN_USERNAME='用户名'
VPN_PASSWORD='密码'
```
2. 配置strongSwan
```bash
cat > /etc/ipsec.conf <<EOF
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
# strictcrlpolicy=yes
# uniqueids = no
# Add connections here.
# Sample VPN connections
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
authby=secret
ike=aes128-sha1-modp1024,3des-sha1-modp1024!
esp=aes128-sha1-modp1024,3des-sha1-modp1024!
conn myvpn
keyexchange=ikev1
left=%defaultroute
auto=add
authby=secret
type=transport
leftprotoport=17/1701
rightprotoport=17/1701
right=$VPN_SERVER_IP
EOF
cat > /etc/ipsec.secrets <<EOF
: PSK "$VPN_IPSEC_PSK"
EOF
chmod 600 /etc/ipsec.secrets
# For CentOS/RHEL & Fedora ONLY
mv /etc/strongswan/ipsec.conf /etc/strongswan/ipsec.conf.old 2>/dev/null
mv /etc/strongswan/ipsec.secrets /etc/strongswan/ipsec.secrets.old 2>/dev/null
ln -s /etc/ipsec.conf /etc/strongswan/ipsec.conf
ln -s /etc/ipsec.secrets /etc/strongswan/ipsec.secrets
```
3. 配置xl2tpd
```bash=
cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[lac myvpn]
lns = $VPN_SERVER_IP
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes
EOF
cat > /etc/ppp/options.l2tpd.client <<EOF
ipcp-accept-local
ipcp-accept-remote
refuse-eap
require-chap
noccp
noauth
mtu 1280
mru 1280
noipdefault
defaultroute
usepeerdns
connect-delay 5000
name $VPN_USER
password $VPN_PASSWORD
EOF
chmod 600 /etc/ppp/options.l2tpd.client
```
4. 连接VPN
```bash=
mkdir -p /var/run/xl2tpd
touch /var/run/xl2tpd/l2tp-control
service strongswan restart
service xl2tpd restart
## 连接VPN
strongswan up myvpn
echo "c myvpn" > /var/run/xl2tpd/l2tp-control
## 断开VPN
echo "d myvpn" > /var/run/xl2tpd/l2tp-control
strongswan down myvpn
```
## 扩展知识
比较一下现在主流VPN协议的优缺点
### PPTP
点对点隧道协议(英语:Point to Point Tunneling Protocol,缩写为PPTP)是实现虚拟专用网(VPN)的方式之一。PPTP使用传输控制协议(TCP)创建控制通道来发送控制命令,以及利用通用路由封装(GRE)通道来封装点对点协议(PPP)数据包以发送资料。这个协议最早由微软等厂商主导开发,但因为它的加密方式容易被破解,微软已经不再建议使用这个协议。
#### 优点
- 速度快
- 几乎所有平台都内置
- 配置极为简单
#### 缺点
- 受到美国国安局威胁
- 不安全
### L2TP and L2TP/IPsec
#### 优点
- 可供所有现代的设备及操作系统使用
- 容易设定
#### 缺点
- 比OpenVPN慢
- 可能受到美国国安局的威胁
- 与限制力强的防火请一起使用会有问题
- 美国国安局极有可能已经削弱这个协议的能力
### OpenVPN
OpenVPN是一个用于创建虚拟私人网络加密通道的软件包,最早由James Yonan编写。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证。
它大量使用了OpenSSL加密库中的SSL/TLS协议函数库。
OpenVPN的技术核心是虚拟网卡,其次是SSL协议实现。
#### 优点
- 具备能跨越大多数防火墙的能力
- 高度可配置
- 因为是开放资源,所以可以轻松修正后门
- 能使用各种加密功能运算法
- 高度安全性
#### 缺点
- 设定起来有点棘手
- 需要用到第三方软件
- 桌面电脑支援做得好,可是流动设备的则需要改进
### SSTP
SSTP可以创建一个在HTTPS上传送的VPN隧道,从而消除与基于PPTP(点对点隧道协议)或L2TP(第2层隧道协议)VPN连接有关的诸多问题。因为这些协议有可能受到某些位于客户端与服务器之间的Web代理、防火墙和网络地址转换(NAT)路由器的阻拦。
这种SSTP只适用于远程访问,不能支持站点与站点之间的VPN隧道。
#### 优点
- 具备越过大多数防火墙的能力
- 安全标准取决与密码,但一般来说是安全的
- 能完全融入Windows操作系统
- 微软支援
#### 缺点
- 因为是专利标准是由微软公司持有,因此不能修正后门
- 只能在Windows平台上操作
### IKEv2
因特网密钥交换(英语:Internet Key Exchange,简称IKE或IKEv2)是一种网络协议,归属于IPsec协议族,用以创建安全关系(Security association,SA)。它创建在奥克利协议(Oakley protocol)与ISAKMP协议的基础之上。
#### 优点
- 极度安全–支援各种密码如3DES、 AES、 AES 256等
- 支援黑莓设备
- 稳定,特别是在连接中断或者是交换网络使用时更是如此
- 容易设定,至少从用户终端是如此
- 比 L2TP、PPTP 及 SSTP相对更快速
#### 缺点
- 支援平台有限
- 为基础的方案像是SSTP或OpenVPN而较容易被阻挡,因为使用UDP 端口500
- 不是开放资源实现方案
- 在非服务器端施用IKEv2比较棘手,能导致一些潜在问题
## 参考
- [第二层隧道协议](https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%BA%8C%E5%B1%82%E9%9A%A7%E9%81%93%E5%8D%8F%E8%AE%AE)
- [CentOS 7搭建L2TP VPN](https://www.wenjinyu.me/zh/centos-7-build-l2tp-vpn/#%E5%87%86%E5%A4%87)
- [CentOS7 搭建L2TP](https://www.linuxprobe.com/centos7-install-l2tp.html)
- [Centos7 搭建 L2TP+ IPsec VPN](https://imkira.com/CentOS7-L2TP-IPsec-VPN/)
- [L2TP连接尝试失败,因为安全层再初始化与远程计算机的协商时遇到一个处理错误](https://blog.csdn.net/weixin_44901564/article/details/106619826)
- [比较VPN协议: PPTP 对 L2TP 对 OpenVPN 对SSTP 对 IKEv2](https://zh.vpnmentor.com/blog/%e6%af%94%e8%be%83vpn%e5%8d%8f%e8%ae%ae-pptp-%e5%af%b9-l2tp-%e5%af%b9-openvpn-%e5%af%b9sstp-%e5%af%b9-ikev2/)
- [Configuring L2TP connection on Centos 7](https://www.myip.io/how-to-details/configure-l2tp-centos)