L2tp vpn搭建过程

VPN搭建过程

将 iPhone 的系统升级到 iOS10 之后,系统已经禁止使用 PPTP 类型的 VPN 了,为此我尝试自己搭建 L2TP 类型的 VPN 服务,虽然服务是搭设成功了,但在4G网络下还是会被运营商屏蔽。

无论如何,把整个过程记录下来还是很有必要的,方便以后进行回顾。

系统环境
CentOS 6.7 x64
系统镜像的提供商为 Vultr.com
确认 ppp 是否可用
此步骤和 在 CentOS 中快速搭建 VPN 服务器(PPTP) 是一样的,我们必须拥有操作 ppp 这个设备的权限,才能够继续后面的操作,可以使用以下指令来进行测试。

[root@vultr ~]# cat /dev/ppp
cat: /dev/ppp: 没有那个设备或地址  
若提示“没有那个设备或地址”或者“No such device or address”,都说明 ppp 是可用的,后续的过程才可以被继续执行。

如果出现的是“没有权限”或者“Permission denied”,那么不用继续往下看了,除非你的虚拟主机提供商能够提供选项让你开启PPP,否则没戏。

确定内核是否支持 mppe
[root@vultr ~]# modprobe ppp-compress-18 && echo yes
yes  
[root@vultr ~]# 
若能够返回“yes”,那么说明是支持的,否则就不用继续了。

确认是否开启了 tun
[root@vultr ~]# cat /dev/net/tun
cat: /dev/net/tun: 文件描述符处于错误状态  
若提示“文件描述符处于错误状态”或者“File descriptor in bad state”,都说明 tun 是开启的,后续过程才可以继续执行。

更新 yum 仓库(可选)
可以根据系统的情况选择是否要进行此步骤,如果你在后续过程中发现 yum 指令无法找到我们想要的软件包时,那么可以执行一下此步骤再试试。

yum install update  
yum update -y  
安装 epel 源
由于 CentOS7 的官方源暂时不存在我们需要的 xl2tpd 软件包,所以需要安装一下 epel 的源来补充。

yum install -y epel-release  
安装必要组件
网络上一些老教程使用的是 openswan,而实际上 openswan 已经被 libreswan 取代了,所以我们直接安装 libreswan 即可。
在Centos7上提供L2TP服务的最新程序包为:xl2tpd-1.3.6-8.el7.x86_64,提供IPSEC服务最新程序包为:libreswan-3.15-5.el7_1.x86_64 。在早些版本的LINUX系统提供IPSEC服务是由openswan包提供,但在Centos7中,openswan更名为libreswan.
xl2tpd提供l2tp服务,libreswan提供ipsec服务,在centos7 版本后, 提供ipsec 服务包由libreswan替代了openswan

yum install -y xl2tpd libreswan  
修改 xl2tpd 配置文件
vim /etc/xl2tpd/xl2tpd.conf  
编辑的时候,重点关注的选项如下:

[global]
ipsec saref = yes   // 此选项本来就有,取消左侧的 ; 即可

[lns default]
ip range = 10.8.0.100-10.8.0.254  // 这是拨号上来后分配的IP地址  
local ip = 10.8.0.1  // 本机在虚拟局域网中的IP地址  
refuse chap = yes    // 这个本来应该是 require 的改成 refuse  
refuse pap = yes  
require authentication = yes  
name = LinuxVPNserver  
ppp debug = yes  
pppoptfile = /etc/ppp/options.xl2tpd  
注意:分配IP段的时候,请尽量使用一些少见的段,避免使用 192.168.0 或 192.168.1 这样常用的局域网IP段。

最终,整个文件看起来的样子是(仅供参考,不同的 xl2tp 版本可能略有差异):

;
; 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 = 192.168.1.98
;
; 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 = 10.8.0.100-10.8.0.254  
local ip = 10.8.0.1  
refuse chap = yes  
refuse pap = yes  
require authentication = yes  
name = LinuxVPNserver  
ppp debug = yes  
pppoptfile = /etc/ppp/options.xl2tpd  
修改 pppoptfile 配置
在上面的 xl2tpd 配置文件中,我们可以看到 [lns default] 中 pppoptfile 选项的值是 /etc/ppp/options.xl2tpd 它就是我们 pppoptfile 配置文件的路径

vim /etc/ppp/options.xl2tpd  
清空里面原来的内容,然后修改成如下的内容:

#require-mschap-v2  # 考虑到非微软的设备,这里不要求进行 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  
新增 ipsec 配置文件
在 /etc/ipsec.conf 中实际上已经引用了 /etc/ipsec.d/ 目录中所有后缀为 conf 的配置文件,所以为了方便管理,我们可以新建一个配置文件来写配置。

vim /etc/ipsec.d/l2tp-ipsec.conf  
填写以下内容(请将left选项的值,设置为你服务器的外网IP地址),然后保存退出即可:

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=你服务器的外网IP地址
        leftprotoport=17/1701
        right=%any
        rightprotoport=17/%any
设置共享密钥PSK
与 PPTP 类型的 VPN 不同,L2TP 类型的 VPN 有一个叫“共享密钥”的东西,在建立连接的时候需要用。

vim /etc/ipsec.d/default.secrets  
在刚建立的配置文件中,按照以下格式添加内容(字段之间用空格分隔,而不是TAB):

: PSK “你想设置的共享密钥”
比如:

: PSK "oabc"
这样你的共享密钥就是:oabc 了,注意左侧英文冒号:要留着!

创建 vpn 账号
这个配置文件和 在 CentOS 中快速搭建 VPN 服务器(PPTP) 也是一样的。

vim /etc/ppp/chap-secrets  
账号密码一行一个,格式如下:

VPN账号{TAB}l2tpd{TAB}VPN密码{TAB}*  
注意:这里第二个字段使用的是 l2tpd 而不是 pptpd,使用 pptpd 的话说明这个账号用于登录 PPTP 类型的 VPN 服务;而使用 l2tpd 则表示此账号用于登录 L2TP 类型的 VPN服务。如果不想区分的话,第二个字段可以用星号*替代。

这里提到的 {TAB} 就是按键盘上的 TAB 按键,比如现在我想创建一个用户名为 cairo 密码为 321456 的账号时,我需要在此文件的末尾新增一行:

cairo    l2tpd    321456    *  
注意:请不要直接复制上面这一行,因为博客系统的原因,这里使用的是空格,而不是TAB,直接复制可能会出问题。

加入之后无需重新启动 xl2tpd 服务,立刻生效。

查看本机网卡名称
[root@vultr ~]# cd /proc/sys/net/ipv4/conf/
[root@vultr conf]# ls
all  default  eth0  lo  ppp0  
这里可以看到,本机有 all default eth0 lo ppp0 一共 5 个网卡,这里需要记住以下他们的名字,下一步需要用到。

修改 sysctl 配置
vim /etc/sysctl.conf  
在此配置文件的开头或者末尾处,进行如下调整和修改:

- 将 net.ipv4.ip_forward = 0 的值从 0 改成 1
- 将 net.ipv4.conf.{网卡名称}.accept_redirects 的值添加或修改为 0
- 将 net.ipv4.conf.{网卡名称}.rp_filter 的值添加或修改为 0
- 将 net.ipv4.conf.{网卡名称}.send_redirects 的值添加或修改为 0
最终新增和修改的部分看起来可能会是这样,有几个网卡就添加几组配置:

很奇怪,在 CentOS7 下不需要这么麻烦,只需要添加一组 all 就可以了,而在 CentOS 6.x 中这几个都需要添加,否则 ipsec verify 会报错

net.ipv4.ip_forward = 1

net.ipv4.conf.all.accept_redirects = 0  
net.ipv4.conf.all.rp_filter = 0  
net.ipv4.conf.all.send_redirects = 0

net.ipv4.conf.default.accept_redirects = 0  
net.ipv4.conf.default.rp_filter = 0  
net.ipv4.conf.default.send_redirects = 0

net.ipv4.conf.ppp0.accept_redirects = 0  
net.ipv4.conf.ppp0.rp_filter = 0  
net.ipv4.conf.ppp0.send_redirects = 0

net.ipv4.conf.lo.accept_redirects = 0  
net.ipv4.conf.lo.rp_filter = 0  
net.ipv4.conf.lo.send_redirects = 0

net.ipv4.conf.eth0.accept_redirects = 0  
net.ipv4.conf.eth0.rp_filter = 0  
net.ipv4.conf.eth0.send_redirects = 0  
注意:改完后,看看此配置文件中是否已经存在相同名字的选项,而值却不符合预期的,如果有的话,请把重复的值注释掉,否则会冲突。

最后执行一下 sysctl -p 就可以在不重启的情况下,让配置立刻生效:

[root@vultr conf]# sysctl -p
net.ipv4.ip_forward = 1  
net.ipv4.conf.all.accept_redirects = 0  
net.ipv4.conf.all.rp_filter = 0  
net.ipv4.conf.all.send_redirects = 0  
net.ipv4.conf.default.accept_redirects = 0  
net.ipv4.conf.default.rp_filter = 0  
net.ipv4.conf.default.send_redirects = 0  
net.ipv4.conf.ppp0.accept_redirects = 0  
net.ipv4.conf.ppp0.rp_filter = 0  
net.ipv4.conf.ppp0.send_redirects = 0  
net.ipv4.conf.lo.accept_redirects = 0  
net.ipv4.conf.lo.rp_filter = 0  
net.ipv4.conf.lo.send_redirects = 0  
net.ipv4.conf.eth0.accept_redirects = 0  
net.ipv4.conf.eth0.rp_filter = 0  
net.ipv4.conf.eth0.send_redirects = 0  
net.ipv4.conf.default.rp_filter = 0  
net.ipv4.conf.default.accept_source_route = 0  
kernel.sysrq = 0  
kernel.core_uses_pid = 1  
net.ipv4.tcp_syncookies = 1  
kernel.msgmnb = 65536  
kernel.msgmax = 65536  
kernel.shmmax = 68719476736  
kernel.shmall = 4294967296  
启动 xl2tpd 并设置开机自启动
[root@vultr ~]# service xl2tpd start
Starting xl2tpd:                 [  OK  ]  

systemctl status xl2tpd

[root@vultr ~]# chkconfig xl2tpd on
[root@vultr ~]#
这里有两个指令,service xl2tpd start 是启动服务,chkconfig xl2tpd on 是设置 xl2tpd 服务的开机启动。

验证 ipsec 的配置
执行 ipsec verify 指令,如果能够看到下面的内容,没有红色并且没有FAILED字样的话,那么就验证通过了。

ipsec setup start
看报错,修改sysctl.conf

[root@vultr ~]# ipsec verify
Verifying installed system and configuration files

Version check and ipsec on-path                       [OK]  
Libreswan 3.15 (netkey) on 2.6.32-573.8.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]  
Two or more interfaces found, checking IP forwarding    [OK]  
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]  
[root@vultr ~]#
启动 ipsec 并设置开机自启动
[root@vultr ~]# service ipsec start
Starting pluto IKE daemon for IPsec: .              [  OK  ]  
[root@vultr ~]# chkconfig ipsec on
[root@vultr ~]#
这里有两个指令,service ipsec start 是启动服务,chkconfig ipsec on 是设置 ipsec 服务的开机启动。

查询自己的公网接口名称
[root@vultr ~]# ifconfig
使用上面的 ifconfig 可以看到一些信息,找到你公网IP地址所在的区块,他左侧的接口名称就是了,一般情况下是 eth0,也有可能是 eth1 之类,下面举个例子:

[root@vultr ~]# ifconfig
eth0      Link encap:Ethernet  HWaddr 56:00:00:1F:A0:E2  
          inet addr:107.191.*.*  Bcast:107.*.*.255  Mask:255.255.254.0
          inet6 addr: fe80::****:ff:****:a0e2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:144453 errors:0 dropped:0 overruns:0 frame:0
          TX packets:166057 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:109188702 (104.1 MiB)  TX bytes:106951712 (101.9 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
在这个例子中,我在 eth0 这一段找到了我的公网IP地址 107.191.*.* 所以我的公网网卡接口名称就是 eth0 ,我们记住它,后面用得上。

当然凡事有例外,比如 Oneasiahost 提供商的VPS主机,他的网卡接口不是 eth 开头的,而是 venet 开头的,比如 venet0 。关于 Oneasiahost 的主机多说一句,你会看到你和公网IP地址对应的是类似 venet0:0 但是实际上做主的是 ipv6 地址的 venet0 接口才对。后续步骤中若你填写了 venet0:0 会发现是行不通的,那时候就换成 venet0 试试看吧。

配置 iptables 防火墙
这里我假设你已经执行过 在 CentOS 中快速搭建 VPN 服务器(PPTP) 里面的指令,创建了 iptables 的初步环境:

注意:请将下面指令中的 eth0 替换成你第六步定位到的公网接口名称。

# 如果你已经执行过“在 CentOS 中快速搭建 VPN 服务器(PPTP)”则无需执行这一段指令
[root@vultr ~]# iptables --flush POSTROUTING --table nat
[root@vultr ~]# iptables --flush FORWARD
[root@vultr ~]# iptables -A INPUT -p tcp -m tcp --dport 1723 -j ACCEPT
[root@vultr ~]# iptables -A INPUT -p gre -j ACCEPT
[root@vultr ~]# iptables -t nat -A POSTROUTING -s 192.168.220.0/24 -o eth0 -j MASQUERADE
[root@vultr ~]# service iptables save
[root@vultr ~]# service iptables restart
[root@vultr ~]# chkconfig iptables on
上面的防火墙配置做了两件事情:

放行 PPTP 需要的 1723 TCP 端口
对 192.168.220 网段进行 NAT 映射
接下来,我们要在这个基础上,去放行 L2TP 所需要的端口,以及添加对 10.8.0 网段的 NAT 映射。我们不再使用指令的方式去添加防火墙规则,而是通过直接编辑 /etc/sysconfig/iptables 的方式来实现。

vim /etc/sysconfig/iptables  
在 -A INPUT -p tcp -m tcp --dport 1723 -j ACCEPT 的下方,添加以下规则来放行 L2TP 需要的三个端口:

-A INPUT -p udp -m udp --dport 1701 -j ACCEPT
-A INPUT -p udp -m udp --dport 500 -j ACCEPT
-A INPUT -p udp -m udp --dport 4500 -j ACCEPT

注意:请将下面指令中的 eth0 替换成你第六步定位到的公网接口名称。

在 -A POSTROUTING -s 192.168.240.0/24 -o eth0 -j MASQUERADE 的下方,添加以下规则来对 10.8.0 进行 NAT 映射:

-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
保存配置文件,至此我们的防火墙规则就配置完毕了。

重启 iptables 服务
直接使用 service iptables restart 来完成 iptables 服务的重启工作,如果规则一切正确,那么显示的都是绿色的 [ OK ].

[root@vultr ~]# service iptables restart
iptables: Setting chains to policy ACCEPT: nat filter      [  OK  ]  
iptables: Flushing firewall rules:                         [  OK  ]  
iptables: Unloading modules:                               [  OK  ]  
iptables: Applying firewall rules:                         [  OK  ]  
[root@vultr ~]#
最后: 确认是否成功
当你成功连上 VPN 之后,你可以访问一下类似 http://www.ip138.com 或者 http://www.whatismyip.com.tw/ 来查看自己的IP地址,若已经变成了 VPN 服务器的IP地址的话,就说明已经成功了。

运营商限制
电信和联通运营商,在移动设备使用 3G\4G 网络的时候,屏蔽了 L2TP 协议的 VPN。所以如果想要让手机能连接到 L2TP 类型的 VPN 的话,那么需要先连接某一个 WIFI 才可以。

参考文献
https://www.douban.com/note/266076883/ 
http://sunweiwei.com/1933/ 
http://wangzan18.blog.51cto.com/8021085/1735805 
http://blog.csdn.net/kitvv/article/details/50696585 
https://www.robberphex.com/2015/03/386 
http://blog.csdn.net/kitvv/article/details/50696585 
http://www.cnblogs.com/hanxianlong/p/3923491.html

questions:

but I couldn't find any suitable secret (password) for it to use to do so.
id     *       password     *