22
2016
09

Ubuntu下搭建NAT内网的IPSec over L2TP VPN服务器

近期咱帮一朋友在Ubuntu下搭建了一个IPSec over L2TP的VPN服务器,成功之余写下这篇文章作为笔记同时也给有同样需求且找到这篇博客的网友们。

这件事的起因是因为苹果公司于北京时间2016年9月14日正式推送IOS10给苹果手机用户了,部分升级了的用户会发现IOS10操作系统已经不再支持PPTP VPN了,这可难倒了像咱朋友一样为了省事用PPTP建立内网VPN的网络人,不过,PPTP确实不是一个很好的VPN协议,有很多的硬伤,具体大家可以搜一下,咱就不展开来说了。IOS10支持的VPN有L2TP、IKEv2和IPSec,IKEv2和IPSec虽然都是非常给力的VPN协议,但是配置和维护都比较复杂,咱个人不是很推荐使用,所以就帮我朋友弄了一个IPSec over L2TP的服务器了。

 

多数情况下我们会把L2TP服务器放在内网,防火墙的后面,所以为了让L2TP正常工作,我们需要在防火墙上允许这么几个端口:TCP1701(L2TP)、Protocol ID 47(GRE)、UDP500(IKE)以及UDP4500(NAT-T)。


搭建IPSec over L2TP服务器首先得在服务器上装操作系统,咱这用的是Ubuntu 14.04.5 LTS的操作系统,然后就是要安装应用,IPSec over L2TP主要要用到的程序有两个,L2TP的程序xl2tpd和加密程序openswan,这两个程序都可以用apt-get的方式直接获取,不过在获取之前咱建议用apt-get update命令升级到最新版本,升级到最新版本之后在执行apt-get install xl2tpd openswan安装我们要的两个程序,注意如果登录的账号不是root的话,需要在命令前面加上sudo提权。执行命令后获取到并安装的服务器上的版本分别为Openswan IPsec 2.6.38和xl2tpd 1.3.6。

安装完成后,首先我们来配置:

 

Step 1. 配置IPSec,IPSec的配置保存在文件/etc/ipsec.conf里面,默认这个文件是存在的,所以首先我们可以把这个文件重命名为ipsec.config.bak,然后再vi命令新建一个ipsec.conf文件,文件内容如下:

version 2

 

config setup
    dumpdir=/var/run/pluto/
    nat_traversal=yes
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v6:fd00::/8,%v6:fe80::/10
    protostack=netkey
    force_keepalive=yes
    keep_alive=60

 

conn L2TP-PSK-noNAT
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    ikelifetime=8h
    keylife=1h
    ike=aes256-sha1,aes128-sha1,3des-sha1,aes256-sha2_256
    phase2alg=aes256-sha1,aes128-sha1,3des-sha1,aes256-sha2_256
    sha2_truncbug=yes
    type=transport

    #left这里写的是服务器的IP地址
    left=222.333.111.222
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    dpddelay=10
    dpdtimeout=20
    dpdaction=clear

 Step 2. IPSec配置完之后还需要配置预共享密钥,这个密钥是用来协商加密方式的,配置文件是/etc/ipsec.secrets,只需要在配置文件里加上下面一行就可以了:

#从做到右依次是“服务器IP”、“允许使用key的IP”和“预共享密钥(PSK后面双引号里面的内容)”

10.0.0.77  %any:   PSK "randstadchina"

Step 3. 上面两步完成了IPSec的配置,接下来就是要配置L2TP了,L2TP的配置文件是/etc/xl2tpd/xl2tpd.conf,这个文件同样也已经存在了,建议修改为xl2tp.conf.bak备份,然后新建一个xl2tpd.conf文件,文件内容如下:

[global]

ipsec saref = yes
saref refinfo = 30

#后面四个debug是用";"注释掉了的,如果出现问题可以将";"去掉借助debug信息排错

;debug avp = yes
;debug network = yes
;debug state = yes
;debug tunnel = yes

 

[lns default]

#这里定义的是用户拨L2TP上来之后获取到的IP地址范围,可以自定义
ip range = 192.168.100.100-192.168.100.200

#这里是用户拨上L2TP之后获取到的Remote IP,也就是服务器IP

local ip = 192.168.100.1
refuse pap = yes
require authentication = yes

#这里的debug跟上面的debug一样,需要的时候开启就可以了

;ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

Step 4. 细心的朋友会发现上面的pppoptfile指定了一个option文件,所以我们需要创建这个文件,路径/etc/ppp/options.xl2tpd,然后再把下面的内容添加到这个文件里:
require-mschap-v2

#这一段主要是要注意下面两个,这两个是拨L2TP之后获取到的DNS,很重要的哦

ms-dns 192.168.1.11
ms-dns 192.168.2.22
auth

#因为IPSec包头比较大,所以MTU和MRU要稍微改小,不清楚的话就照抄这两个就可以了
mtu 1200
mru 1000
crtscts
hide-password
modem
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

Step 5. 配置了L2TP和IPSec,当然还需要添加账号,这里的账号是分配给用户拨号的账号,账号文件路径是/etc/ppp/chap-secrets,通过以下格式添加:

#从左往右依次表示“用户名”、“允许使用的协议”、“用户密码”以及“允许拨入的IP(*表示所有)”

user1    l2tp    password1    *

到此为止呢,IPSec over L2TP基本上就配置完了,但是还有几个问题需要解决,首先就是Ubuntu默认不支持IP转发,需要开启IP转发,否则的话拨入的用户无法正常访问其他内网节点。然后就是IPSec over L2TP有很多组件,重启一下什么的很麻烦,所以我们考虑用bash脚本实现。最后就是网段可达的问题,在我朋友的这个案例里,他们无法配置核心路由器增加VPN用户的网段,所以我们考虑使用NAT,让拨入的用户NAT成服务器的IP地址,就没有这个问题了。下面我们来一一解决。

 

Step 5. 首先是允许IP转发(据说新版本的Ubuntu装了L2TP就会自动开启转发,具体我没试过,大家可以留一下),需要修改的是/etc/sysctl.conf这个文件,简单一点的话我们可以直接运行下面的命令,就不需要去修改文件了。

echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.accept_redirects = 0" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.send_redirects = 0" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.default.rp_filter = 0" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.default.accept_source_route = 0" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.default.send_redirects = 0" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.icmp_ignore_bogus_error_responses = 1" | sudo tee -a /etc/sysctl.conf
sysctl -p

Step 6. 然后我们来写一个脚本执行所有组件,NAT部分的配置我们也写在这个脚本里面,新建一个文件/etc/init.d/l2tp.vpn,文件内容如下:

case "$1" in

#下列内容是运行/etc/init.d/l2tp.vpn start时执行的脚本
  start)
echo "Starting L2TP VPN"

#这里就是增加NAT功能的命令,如果可以修改内网路由的话,建议不要启用NAT。
iptables  -t nat   -A POSTROUTING -o eth0 -s 192.168.100.0/24 -j MASQUERADE

echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
    echo 0 > $each/accept_redirects
    echo 0 > $each/send_redirects
done
/etc/init.d/ipsec start
/etc/init.d/xl2tpd start
;;

#下列内容是运行/etc/init.d/l2tp.vpn stop时执行的脚本

stop)
echo "Stopping L2TP VPN"

#这里是清空NAT配置的命令,如果没有做NAT,这条可以省略
iptables --table nat --flush
echo 0 > /proc/sys/net/ipv4/ip_forward
/etc/init.d/ipsec stop
/etc/init.d/xl2tpd stop
;;

#下列内容是运行/etc/init.d/l2tp.vpn restart时执行的脚本

restart)
echo "Restarting L2TP VPN"
iptables  -t nat   -A POSTROUTING -o eth0 -s 192.168.200.0/24 -j MASQUERADE

echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
    echo 0 > $each/accept_redirects
    echo 0 > $each/send_redirects
done
/etc/init.d/ipsec restart
/etc/init.d/xl2tpd restart
 
;;
  *)
 echo "Usage: /etc/init.d/ipsec.vpn  {start|stop|restart}"
 exit 1
  ;;
esac

默认情况下这个文件是不允许执行的,所以需要用命令“chmod 755 /etc/init.d/l2tp.vpn”允许文件被执行。同时还需要通过下面的命令关闭默认的脚本启用我们自建的脚本:

update-rc.d -f ipsec remove
update-rc.d l2tp.vpn defaults

到此,IPSec over L2TP就全部配置完了,启用服务只需要通过命令/etc/init.d/l2tp.vpn start就可以了,也可以通过/etc/init.d/l2tp.vpn restart重启服务,/etc/init.d/l2tp.vpn stop停止服务,接下来,我们用/etc/init.d/l2tp.vpn start命令启动IPSec over L2TP,启动成功与否可以通过service ipsec statue命令查看,或者通过cat /var/log/auth.log | grep pluto命令查看是否有“IPsec SA established transport mode”这个内容,有的话基本上就说明启用成功了。

然后我们在使用的过程中还碰到了Windows无法连接和安卓手机无法连接的问题,下面分享一下我们的解决方案:

1、Windows下不能连L2TP over IPSec的原因
可能是是因为 Windows 下面默认不允许不加密的 IPSec ,需要修改一下注册表:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters ”主键,
 新建 DWORD值:
 键值:ProhibitIpSec
数据类型:REG_DWORD
数值改成 1

之后就解决问题了,但是L2TP连不上的原因很多,这只是众多解决方案的其中之一,具体大家可以谷歌百度查查。

2、安卓无法使用

这个问题我上面写的内容里已经包括解决方案了,具体的话可以参考这个URL:https://code.google.com/p/android/issues/detail?id=196939,问题原因在Floor #30,解决方案在Floor #35、#70、#123或者尝试使用NordVPN客户端。

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。