举个栗子

好读书,不求甚解

Centos7 搭建L2TP+IPsec VPN

Kevalin's Avatar 2023-02-22

Centos7 搭建L2TP+IPsec VPN

L2TP是一种工业标准的Internet隧道协议,功能大致和PPTP协议类似,比如同样可以对网络数据流进行加密。不过也有不同之处,比如PPTP要求网络为IP网络,L2TP要求面向数据包的点对点连接;PPTP使用单一隧道,L2TP使用多隧道;L2TP提供包头压缩、隧道验证,而PPTP不支持。L2TP本身不提供加密功能, 经常搭配IPsec加密协议一起使用, 可以提供比PPTP更高级别的数据加密。

前期准备

检查L2TP需要的环境支持

1
2
3
4
5
# 查看主机是否支持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

开始安装

1
2
3
4
5
6
7
8
9
10
11
12
# 先更新
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
;
; 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# /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密钥

1
2
# 格式为 服务器IP %any: PSK “预共享密钥”,其中 %any: 和 PSK 之间有空格
[服务器外网IP] %any: PSK "123456abcdefg"

接着继续配置服务器, 修改配置文件/etc/ipsec.d/l2tp-ipsec.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

1
2
3
# Secrets for authentication using CHAP
# client server secret IP addresses
vpntest l2tpd 123456 192.168.100.129

这里我习惯性的给用户指定固定IP, 方便管理, 如果你是使用*代替, 那就会自动分配指定段的IP地址

开启内核转发

配置文件/etc/sysctl.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 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

完了, 重载内核配置

1
sysctl -p

配置ip转发

1
2
3
4
5
## ip为服务器内网ip
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j MASQUERADE

## 查看nat配置
iptables -t nat -L -n

启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
## 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 客户端
1
2
3
4
5
6
7
8
yum -y install epel-release
yum -y install strongswan xl2tpd

## 设置 VPN 变量
VPN_SERVER_IP='VPN服务器IP'
VPN_IPSEC_PSK='PSK密钥'
VPN_USERNAME='用户名'
VPN_PASSWORD='密码'
  1. 配置strongSwan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
  1. 配置xl2tpd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
  1. 连接VPN
1
2
3
4
5
6
7
8
9
10
11
12
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比较棘手,能导致一些潜在问题

参考

本文作者 : Kevalin
本文使用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
本文链接 : https://kevalin.github.io/2023/02/22/Centos7-%E6%90%AD%E5%BB%BAL2TP-IPsec-VPN/