CentOS 7搭建L2TP VPN




VPN(Virtual Private Network,即“虚拟私人网络”)是一种通过在数据传输过程中加密的方式来保障数据传输安全的通信方式,L2TP是其中的一种加密方式。VPN被人熟知是可以用来翻墙,不过翻墙不是VPN的主要功能,如果搭建VPN纯粹用来翻墙,可以参考翻墙利器SS,搭建教程:CentOS 搭建 Shadowsocks (ss),SS是纯粹用来翻墙的,所以稳定性和传输速度损耗的控制均比VPN好,不过,后来SS作者被请去喝茶了,原来的SS也就没再更新,也就有了SSR,算是SS的另外一个会更新的分支:ssrpanel:搭建shadowsocksr流量监控和用户管理面板

L2tp的搭建比较繁琐,涉及的部件较多,所以本文也略长,如有任何疑问或看不懂的地方,欢迎留言。

准备

搭建L2TP需要环境支持,所以需要提前查看是否支持,不支持的自行Google

1
2
3
4
5
6
# 查看主机是否支持pptp,返回结果为yes就表示通过
modprobe ppp-compress-18 && echo yes

# 查看是否开启了TUN
# 有的虚拟机主机需要开启,返回结果为**cat: /dev/net/tun: File descriptor in bad state**。就表示通过。
cat /dev/net/tun

安装

L2TP VPN的支持需要以下组件:

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

1
2
# 编辑xl2tpd配置文件
vim /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.<font>

[global]
listen-addr = 服务器内网IP # 去掉前面的分号,并将=后面改为服务器本地IP
auth file = /etc/ppp/chap-secrets # 添加本行
port = 1701 # 添加本行
;
; 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

[lns default]
ip range = 192.168.1.128-192.168.1.254 #设置ip池,ip range是分配给用户的ip,有多少个用户就需要分配多少ip,所以建议分配多一点
local ip = 192.168.1.99 # local ip是分配给本机的ip
require chap = yes
refuse pap = yes
require authentication = yes
name = LinuxVPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

ppp

1
2
# 编辑pppoptfile文件
vim /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
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 xl2tpd
noccp #前面不加#
auth
crtscts
idle 1800
mtu 1410 #第一次配置不建议设置mtu,mru,否则可能789错误
mru 1410
nodefaultroute
debug
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

1
2
# 修改ipsec 主配置文件
vim /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
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
60
61
62
63
64
# /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
# which IPsec stack to use, "netkey" (the default), "klips" or "mast".
# For MacOSX use "bsd"
protostack=netkey
#
# Normally, pluto logs via syslog. If you want to log to a file,
# specify below or to disable logging, eg for embedded systems, use
# the file name /dev/null
# Note: SElinux policies might prevent pluto writing to a log file at
# an unusual location.
#logfile=/var/log/pluto.log
#
# The interfaces= line is only required for the klips/mast stack
#interfaces="%defaultroute"
#interfaces="ipsec0=eth0 ipsec1=ppp0"
#
# If you want to limit listening on a single IP - not required for
# normal operation
#listen=127.0.0.1
#listen=127.0.0.1
#
# Do not set debug options to debug configuration issues!
#
# plutodebug / klipsdebug = "all", "none" or a combation from below:
# "raw crypt parsing emitting control kernel pfkey natt x509 dpd
# private".
# Note: "crypt" is not included with "all", as it can show confidential
# information. It must be specifically specified
# examples:
# plutodebug="control parsing"
# plutodebug="all crypt"
# Again: only enable plutodebug or klipsdebug when asked by a developer
#plutodebug=none
#klipsdebug=none
#
# Enable core dumps (might require system changes, like ulimit -C)
# This is required for abrtd to work properly
# Note: SElinux policies might prevent pluto writing the core at
# unusual locations
dumpdir=/var/run/pluto/
#
# 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 upto 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

# For example connections, see your distribution's documentation directory,
# or https://libreswan.org/wiki/
#
# There is also a lot of information in the manual page, "man ipsec.conf"
#
# It is best to add your IPsec connections as separate files in /etc/ipsec.d/

注意

  • 此配置文件不加 left=服务器ipinclude /etc/ipsec.d/*.conf 或者其他行
  • 第一行config setup必须左对齐,即前面不能有空格,否则会报错
  • 其他每一行都必须以Tab开头,否则会报错
  • 如果安装的是 openswan,可能需要在 config setup 之前添加 version 2.0

IPSec

先设置预共享密钥PSK

1
2
# 编辑配置文件
vim /etc/ipsec.secrets

配置文件如下:

1
2
include /etc/ipsec.d/*.secrets
1.2.3.4 %any: PSK "wenjinyu"

接下来是配置服务器

1
2
# 修改/etc/ipsec.d/l2tp_psk.conf文件
vim /etc/ipsec.d/l2tp_psk.conf

配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
dpddelay=30
dpdtimeout=120
dpdaction=clear
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=1.2.3.4 #修改为服务器IP
leftprotoport=17/1701
right=%any
rightprotoport=17/%any

注意

  • conn开头的两行必须左对齐,开头不能有空格,其他每一行必须以Tab开头

添加账号密码

1
vim /etc/ppp/chap-secrets

配置文件如下:

1
2
3
# Secrets for authentication using CHAP
# client server secret IP addresses
user * passwd *

配置形式为 用户名+*+密码+*

  • 第一个星号是服务类型,在这里是L2TP,因为PPTP的账号密码管理文件也是此文件,所以以通配符*代替更好
  • 第二个星号是用户地址限制,如果填进去某个IP,则是限制只能此IP连接该VPN

开启内核转发

必须开启此项,连接VPN时才能访问公网,不然只能访问服务器内网

1
vim /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
60
61
62
63
64
# 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

//以下三行在我的服务器报错,所以注释掉了,如果没报错则不用注释
#net.ipv6.conf.all.disable_ipv6 = 1
#net.ipv6.conf.default.disable_ipv6 = 0
#net.ipv6.conf.lo.disable_ipv6 = 1

重新加载内核配置项,使刚才的更改生效

1
sysctl -p

如果输出结果有显示 net.ipv4.ip_forward = 1 ,则说明更改生效

测试

开启IPSec

1
ipsec setup start

ipsec setup start等同于service ipsec start提示信息如下:

1
2
Redirecting to: service ipsec start
Starting pluto IKE daemon for IPsec: [ OK ]

确认IPSec状态

1
ipsec verify

如果配置正确,那么提示信息应该像这个样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Verifying installed system and configuration files

Version check and ipsec on-path [OK]
Libreswan 3.15 (netkey) on 2.6.32-696.16.1.el6.x86_64
Checking for IPsec support in kernel [OK]
NETKEY: Testing XFRM related proc values
ICMP default/send_redirects [OK]
ICMP default/accept_redirects [OK]
XFRM larval drop [OK]
Pluto ipsec.conf syntax [OK]
Hardware random device [N/A]
Checking rp_filter [OK]
Checking that pluto is running [OK]
Pluto listening for IKE on udp 500 [OK]
Pluto listening for IKE/NAT-T on udp 4500 [OK]
Pluto ipsec.secret syntax [OK]
Checking 'ip' command [OK]
Checking 'iptables' command [OK]
Checking 'prelink' command does not interfere with FIPSChecking for obsolete ipsec.conf options [OK]
Opportunistic Encryption [DISABLED]

如果有错误信息,部分问题解决如下:

1
Pluto listening for IKE on udp 500            [FAILED]

解决办法:安装 lsofyum install lsof

1
Checking NAT and MASQUERADEing           [N/A]

解决办法:更改iptables规则:iptables -t nat -A POSTROUTING -j MASQUERADE

1
can not load config '/etc/ipsec.conf': /etc/ipsec.conf:58: syntax error, unexpected KEYWORD, expecting $end [rightsubnet]

解决办法:/etc/ipsec.conf 文件除了 conn 开头的两行之外,其他的都要以 Tab缩进 开头

1
SAref kernel support                  [N/A]

解决办法:修改/etc/xl2tpd/xl2tpd.conf

1
2
[global]
ipsec saref = no  # 将yes改为no
1
2
Two or more interfaces found, checking IP forwarding   [FAILED]
Checking NAT and MASQUERADEing           [OK]

解决办法:只要 cat /proc/sys/net/ipv4/ip_forward 返回结果是 1 就没事,如果还不行,就按照上面更改 sysctl.conf 文件

开启xl2tpd

1
service xl2tpd restart

提示信息如下:

1
2
stopping xl2tpd:                                        [  OK  ]
Starting xl2tpd: [ OK ]

xl2tp debug

1
xl2tpd -D

测试连接

关闭iptables:

1
service iptables stop

此时关闭iptables防火墙进行测试,已经可以连上VPN,可以上外网

其他

防火墙iptables设置

不开防火墙裸奔也不是办法,所以将防火墙默认拒绝所有接口,然后开放需要使用的接口即可。

清空防火墙配置:

1
2
3
4
iptables -P INPUT ACCEPT     # 改成 ACCEPT 标示接收一切请求
iptables -F # 清空默认所有规则
iptables -X # 清空自定义所有规则
iptables -Z # 计数器置0

配置防火墙:

1
2
3
4
iptables -A INPUT -i lo -j ACCEPT                                # 允许127.0.0.1访问本地服务
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT # 允许访问外部服务
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT # 允许 ping
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 开启 ssh 端口

配置ip转发:

1
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j MASQUERADE

对iptables规则进行保存:

1
service iptables save

重启iptables,使规则生效:

1
service iptables restart

添加开机自启:

1
2
3
chkconfig iptables on           # 开机启动 iptables
chkconfig xl2tpd on # 开机启动 xl2tpd
chkconfig ipsec on # 开机启动 IPSec

报错修复

运行 ipsec verify 时报错:

1
2
ICMP default/send_redirects    [NOT DISABLED]
ICMP default/accept_redirects   [NOT DISABLED]

根据提示,需要关闭sendredirects和acceptredirects。查看这两个下的所有选项,根据网卡数量,选项个数无法确定,其中也可能会包含IPv6的选项,IPv6的不需要改

1
2
sysctl -a | grep -e 'send_redirects'
sysctl -a | grep -e 'accept_redirects'

可以直接通过下面的脚本把上面显示的所有IPv4的选项全部设置为0

1
2
3
4
5
6
#!/bin/bash
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/send_redirects
echo 0 > $each/accept_redirects
done

修改完成后,再进行一次 ipsec 验证即可看到结果,[NOT DISABLE]已变为[OK]

客户端设置

  1. Windows设置:错误 789、792
    • windows+r 打开运行,输入 services.msc,查找 ipsec policy agent,启用服务
    • 打开注册表,路径HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters
      • 添加DWORD值(32位)值,名称 ProhibitIpSec,值为 1
      • 由于缺省的 Windows XP L2TP 传输策略不允许不使用 IPSec 加密的 L2TP 传输,修改 AllowL2TPWeakCrypto 的值为 1
      • 重启
  2. iOS
    联通移动信号无法连接,只能wifi
  3. Android
    Android对l2tp的支持有bug,所以连不上

后期

CentOS:/var/log/secure
Debian:/var/log/auth.log

小记

配置文件

配置文件路径 设置内容
/etc/xl2tpd/xl2tpd.conf ip池、内网IP
/etc/ppp/options.xl2tpd mtu、dns
/etc/ipsec.conf IPSec主配置文件
/etc/ipsec.secrets 预共享密钥
/etc/ipsec.d/l2tp_psk.conf 服务器IP
/etc/ppp/chap-secrets 帐号密码
/etc/sysctl.conf 开启内核转发
/var/log/secure 日志

所需要安装的软件

软件 作用
libreswan(ipsec) 提供一个密钥
ppp 拨号软件,提供用户名和密码
xl2tpd 提供L2TP服务
sysctl 提供服务器内部转发
iptables 提供请求从服务器内部转向外部,外部响应转向服务器内部




评论