① linux网络协议栈7--ipsec收发包流程
流程路径:ip_rcv() --> ip_rcv_finish() --> ip_local_deliver() --> ip_local_deliver_finish()
解封侧一定是ip报文的目的端,ip_rcv_finish中查到的路由肯定是本机路由(RTCF_LOCAL),调用 ip_local_deliver 处理。
下面是贴的网上的一张图片。
ip_local_deliver_finish中 根据上次协议类型,调用对应的处理函数。inet_protos 中挂载了各类协议的操作集,对于AH或者ESP来说,是xfrm4_rcv,对于ipsec nat-t情况下,是udp协议的处理函数udp_rcv,内部才是封装的ipsec报文(AH或者ESP)。
xfrm4_rcv --> xfrm4_rcv_spi --> xfrm4_rcv_encap --> xfrm_input
最终调用 xfrm_input 做收包解封装流程。
1、创建SKB的安全路径;
2、解析报文,获取daddr、spi,加上协议类型(esp、ah等),就可以查询到SA了,这些是SA的key,下面列出了一组linux ipsec的state(sa)和policy,方便一眼就能看到关键信息;
3、调用SA对应协议类型的input函数,解包,并返回更上层的协议类型,type可为esp,ah,ipcomp等。对应的处理函数esp_input、ah_input等;
4、解码完成后,再根据ipsec的模式做解封处理,常用的有隧道模式和传输模式。对应xfrm4_mode_tunnel_input 和 xfrm4_transport_inout,处理都比较简单,隧道模式去掉外层头,传输模式只是设置一些skb的数据。
5、协议类型可以多层封装,如ESP+AH,所以需要再次解析内存协议,如果还是AH、ESP、COMP,则解析新的spi,返回2,查询新的SA处理报文。
6、经过上面流程处理,漏出了用户数据报文(IP报文),根据ipsec模式:
流程路径如下图,这里以转发流程为例,本机发送的包主要流程类似。
转发流程:
ip_forward 函数中调用xfrm4_route_forward,这个函数:
1、解析用户报文,查找对应的Ipsec policy(__xfrm_policy_lookup);
2、再根据policy的模版tmpl查找对应最优的SA(xfrm_tmpl_resolve),模版的内容以及和SA的对应关系见上面贴出的ip xfrm命令显示;
3、最后根据SA生成安全路由,挂载再skb的dst上; 一条用户流可以声明多个安全策略(policy),所以会对应多个SA,每个SA处理会生成一个安全路由项struct dst_entry结构(xfrm_resolve_and_create_bundle),这些安全路由项通过 child 指针链接为一个链表,其成员 output挂载了不同安全协议的处理函数,这样就可以对数据包进行连续的处理,比如先压缩,再ESP封装,再AH封装。
安全路由链的最后一个路由项一定是普通IP路由项,因为最终报文都得走普通路由转发出去,如果是隧道模式,在tunnel output封装完完成ip头后还会再查一次路由挂载到安全路由链的最后一个。
注: SA安全联盟是IPsec的基础,也是IPsec的本质。 SA是通信对等体间对某些要素的约定,例如使用哪种协议、协议的操作模式、加密算法、特定流中保护数据的共享密钥以及SA的生存周期等。
然后,经过FORWARD点后,调用ip_forward_finish()-->dst_output,最终调用skb_dst(skb)->output(skb),此时挂载的xfrm4_output
本机发送流程简单记录一下,和转发流程殊途同归:
查询安全路由: ip_queue_xmit --> ip_route_output_flow --> __xfrm_lookup
封装发送: ip_queue_xmit --> ip_local_out --> dst_output --> xfrm4_output
注:
1). 无论转发还是本地发送,在查询安全路由之前都会查一次普通路由,如果查不到,报文丢弃,但这条路由不一定需要指向真实的下一跳的出接口,只要能匹配到报文DIP即可,如配置一跳其它接口的defualt。
2). strongswan是一款用的比较多的ipsec开源软件,协商完成后可以看到其创建了220 table,经常有人问里面的路由有啥用、为什么有时有有时无。这里做个测试记录: 1、220中貌似只有在tunnel模式且感兴趣流是本机发起(本机配置感兴趣流IP地址)的时候才会配置感兴趣流相关的路由,路由指定了source;2、不配置也没有关系,如1)中所说,只要存在感兴趣流的路由即可,只不过ping的时候需要指定source,否者可能匹配不到感兴趣流。所以感觉220这个表一是为了保证
ipsec封装发送流程:
xfrm4_output-->xfrm4_output_finish-->xfrm_output-->xfrm_output2-->xfrm_output_resume-->xfrm_output_one
xfrm4_output 函数先过POSTROUTING点,在封装之前可以先做SNAT。后面则调用xfrm_output_resume-->xfrm_output_one 做IPSEC封装最终走普通路由走IP发送。
贴一些网上的几张数据结构图
1、安全路由
2、策略相关协议处理结构
3、状态相关协议处理结构
② 如何在 Debian / Ubuntu 服务器上架设 L2TP / IPSec VPN
首先解释一个问题:在 iPhone 的 VPN 设置接口里(Settings >> General >> Network >> VPN),你可以看到三个标签:L2TP, PPTP, IPSec。但上面我们又讲本次介绍的 VPN 方式叫“L2TP / IPSec”,这两者究竟是什么关系?
这三个标签确实令人混淆,准确的写法应该是:L2TP over IPSec, PPTP, Cisco IPSec。PPTP 跟另外两者关系不大,且大家较为熟悉,暂且不提,L2TP 和 IPSec 的区别如下。
L2TP:一个“包装”协议,本身并不提供加密和验证的功能。
IPSec:在 IP 数据包的层级提供加密和验证功能,确保中间人无法解密或者伪造数据包。
本来,只用 IPSec 就可以实现 VPN,Mac OS X 和 Linux 都支持。但是 Mac OS X 和 iPhone OS 都推荐使用 L2TP over IPSec,在两者的图形接口上也只能设置这个。L2TP / IPSec 是业界标准,微软也支持。而只用 IPSec 的常见于 Linux-to-Linux 的应用,比如将两个位于不同地区的办公室网络安全地连在一起。这多是固定 IP 路由器到固定 IP 路由器级别的连接,只需保证数据包不被中途截获或者伪造就可以,故使用 L2TP 的意义不大。L2TP / IPSec 主要是实现所谓“Road Warrior”的设置,即用变动的客户端连固定的服务器。
Cisco 的 VPN 用的也是 IPSec 加密,但那是一套不同于 L2TP 的私有包装协议,用于提供用户管理之类的功能,因此一般都需要用 Cisco 自家的 VPN 客户端连接。iPhone / iPad 的 VPN 设置接口中的 IPSec 标签里有 Cisco 的标识,就是这个原因。
以下是在 Ubuntu 和 Debian 主机上架设 L2TP / IPSec VPN 的步骤,一共十四步。你需要有服务器的 root 权限(所以 DreamHost, BlueHost, MediaTemple 这些服务供应商帮你把一切打点周到的主机就无缘了),也需要一些基本的 Linux 知识。不然的话,我们还是推荐您找一位比较熟技术的朋友帮忙。
一、安装 IPSec。如上所述,IPSec 会对 IP 数据包进行加密和验证。这意味着你的电脑 / 移动设备与服务器之间传输的数据无法被解密、也不能被伪造。我推荐用 openswan 这个后台软件包来跑 IPSec。
用以下命令安装 openswan:
sudo aptitude install openswan二、用文字编辑器打开 /etc/ipsec.conf,改成这样:
version 2.0
config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
oe=off
protostack=netkey
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=YOUR.SERVER.IP.ADDRESS
leftprotoport=17/1701
right=%any
rightprotoport=17/%any三、用文字编辑器打开 /etc/ipsec.secrets,改成这样:
YOUR.SERVER.IP.ADDRESS %any: PSK "YourSharedSecret"(别忘了把“YOUR.SERVER.IP.ADDRESS”这部分换成你的服务器的 IP 地址,把“YourSharedSecret”部分换成随便一个字串,例如你喜欢的一句话,等等。)
四、运行以下命令:
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done五、检查一下 IPSec 能否正常工作:
sudo ipsec verify如果在结果中看到“Opportunistic Encryption Support”被禁用了,没关系,其他项 OK 即可。
六、重启 openswan:
sudo /etc/init.d/ipsec restart七、安装 L2TP。常用的 L2TP 后台软件包是 xl2tpd,它和 openswan 是同一帮人写的。
运行以下命令:
sudo aptitude install xl2tpd八、用文字编辑器打开 /etc/xl2tpd/xl2tpd.conf,改成这样:
[global]
ipsec saref = yes
[lns default]
ip range = 10.1.2.2-10.1.2.255
local ip = 10.1.2.1
;require chap = yes
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes这里要注意的是 ip range 一项里的 IP 地址不能和你正在用的 IP 地址重合,也不可与网络上的其他 IP 地址冲突。
九、安装 ppp。这是用来管理 VPN 用户的。
sudo aptitude install ppp十、检查一下 /etc/ppp 目录里有没有 options.xl2tpd 这个文件,没有的话就建一个,文件内容如下:
require-mschap-v2
ms-dns 208.67.222.222
ms-dns 208.67.220.220
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4注意 ms-dns 两行我填的是 OpenDNS。如果你想用其他的 DNS 服务器(例如谷歌的公共 DNS),请自行更换。
十一、现在可以添加一个 VPN 用户了。用文字编辑器打开 /etc/ppp/chap-secrets:
# user server password ip
test l2tpd testpassword *如果你之前设置过 PPTP VPN,chap-secrets 文件里可能已经有了其他用户的列表。你只要把 test l2tpd testpassword * 这样加到后面即可。
十二、重启 xl2tpd:
sudo /etc/init.d/xl2tpd restart十三、设置 iptables 的数据包转发:
iptables --table nat --append POSTROUTING --jump MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward十四、因为某种原因,openswan 在服务器重启后无法正常自动,所以我们可以在 /etc/rc.local 文件里写入如下语句:
iptables --table nat --append POSTROUTING --jump 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到这里,设置工作已经基本完成。你可以用 iPhone 或 iPad 试着连一下。记得在“Secret”中填入你在上述第三步里填的 YourSharedSecret。
如果连接成功,上网也没问题的话,恭喜你,大功告成。如果连不上,恐怕还得多做一步。
Ubuntu 9.10 自带的 openswan 版本是 2.6.22, Debian Lenny 带的版本是 2.4.12。这两个版本的 openswan 都有问题。我们的测试结果表明,2.6.24 版的 openswan 可以在上述两版的 Linux 操作系统下正常工作。所以如果做完以上十四步还是连不上的话,请考虑从源码编译 openswan 2.6.24
③ 群晖NAS安装VPN Server 套件三种服务协议设定
我们在群晖nas里安装VPN Server 套件可以把我们的群晖nas变成一个VPN服务器,我们可以安全的在远端存取Synology NAS 局域网内分享的资源,群晖的VPN server整合了常用的通讯协定: PPTP、OpenVPN 、 L2TP/IPSec,当我们启用了nas的vpn服务,会影响系统的网络性能。
我们先来了解一下三种协议:
PPTP
PPTP (Point-to-Point Tunneling Protocol,点对点信道协议) 是常用的 VPN 解决方案,且大多数的客户端 (包含 Windows、Mac、Linux 及行动装置) 皆支持。
若要启动 PPTP VPN 服务器:
1、开启 VPN Server 并前往左侧面板的 PPTP。
2、勾选启动 PPTP VPN 服务器。
3、在动态 IP 地址字段输入 VPN 服务器的虚拟 IP 地址。请参阅下方的关于动态 IP 地址来了解更多信息。
4、设定最大联机数量来限制 VPN 联机的共同联机数量。
5、设定同一账号最多联机数量来限制使用同一个账号所进行 VPN 联机的共同联机数量。
6、从认证下拉式选单中选择下列任一项目来认证 VPN 客户端:
PAP:认证过程中,将不加密 VPN 客户端的密码。
MS-CHAP v2:认证过程中,将使用 Microsoft CHAP version 2 加密 VPN 客户端的密码。
7、若您选择 MS-CHAP v2 验证,请从加密下拉式选单中选择下列任一项目来加密 VPN 联机:
No MPPE:VPN 联机不会受到加密机制保护。
Optional MPPE:客户端设定将决定 VPN 联机会 / 不会受到 40-bit 或 128-bit 加密机制保护。
Require MPPE:客户端设定将决定 VPN 联机会受到 40-bit 或 128-bit 加密机制保护。
8、设定 MTU (最大传输单元) 来限制 VPN 网络传输的数据封包大小。
9、勾选手动设定 DNS 并指派 DNS 服务器的 IP 地址来发送给 PPTP 客户端。若停用此选项,则会将 Synology NAS 目前所使用的 DNS 服务器发送给客户端。
10、单击套用来让变更生效。
注意:
联机至 VPN 时,VPN 客户端的验证及加密设定必须与 VPN Server 上的相同,否则客户端将无法成功联机。
为兼容于运行在 Windows、Mac OS、iOS 与 Android 系统的大部分 PPTP 客户端,预设的 MTU 值为 1400。若您的网络环境较为复杂,可能需要设定一个较小的 MTU 值。若您经常收到逾时讯息或联机不稳定,请降低 MTU 值。
请检查 Synology NAS 与路由器上的端口转送规则与防火墙设定,确认 TCP 1723 端口已开启。
部分路由器内建 PPTP VPN 服务,因此可能已占用 1723 端口。您需先透过路由器的管理接口关闭其内建的 PPTP VPN 服务,才能确保 VPN Server 上的 PPTP VPN 服务可以正常运作。此外,部分旧式路由器可能会封锁 GRE 协议 (IP 协议 47),造成 VPN 联机失败;建议使用支持 VPN pass-through 联机的路由器。
OpenVPN
OpenVPN 是开放原始码的 VPN 服务解决方案,会以 SSL / TLS 加密机制保护 VPN 联机。
若要启动 OpenVPN VPN 服务器:
1、开启 VPN Server,前往左侧面板的 OpenVPN。
2、勾选启动 OpenVPN 服务器。
3、在动态 IP 地址字段输入 VPN 服务器的虚拟内部 IP 地址。请参阅下方的关于动态 IP 地址来了解更多信息。
4、设定最大联机数量来限制 VPN 联机的共同联机数量。
5、设定同一账号最多联机数量来限制使用同一个账号进行 VPN 联机的共同联机数量。
6、为 OpenVPN 数据传输设定端口与通讯协议。您可以决定要将何种协议的数据封包透过 VPN 转送至 Synology NAS 的哪个端口。默认值为 UDP 端口 1194
注意: 为确保 Synology NAS 上的服务可以正常运作,请避免将同样的一组端口与通讯协议指派给其他 Synology 服务。请参阅此篇应用教学以了解更多信息。
7、在加密下拉式选单中择一,以加密 VPN 信道中的数据封包。
8、在验证下拉式选单中择一,以验证 VPN 客户端。
9、若要在传输数据时压缩数据,请勾选启动 VPN 压缩联机。此选项可提升传输速度,但可能会消耗较多系统资源。
10、勾选允许客户端存取服务器的局域网络来让客户端存取服务器的局域网络。
11、勾选启动 IPv6 服务器模式来启动 OpenVPN 服务器,以传送 IPv6 地址。您必须先在控制面板 > 网络 > 网络接口中,透过 6in4/6to4/DHCP-PD 取得 Prefix,并在此页面中选择该 Prefix。
12、单击套用来让变更生效。
注意:
VPN Server 不支持站台对站台的桥接模式。
请检查 Synology NAS 与路由器上的端口转送规则与防火墙设定,确认 UDP 1194 端口已开启。
在 Windows Vista 或 Windows 7 上执行 OpenVPN GUI 时,请注意,UAC (用户帐户控制) 预设为开启。此设定开启时,需使用以系统管理员身份执行选项来透过 OpenVPN GUI 进行联机。
在 Windows 上透过 OpenVPN GUI 启动 IPv6 服务器模式时,请注意以下事项:
VPN 所使用的接口名称不可包含空格,例如:LAN 1 须变更为 LAN1。
重新导向网关 (redirect-gateway) 选项须由客户端于 openvpn.ovpn 档案中设定。若您不想设定此选项,应手动设定 VPN 接口的 DNS。您可以使用 Google IPv6 DNS:2001:4860:4860::8888。
若要汇出配置文件:
单击汇出配置文件。OpenVPN 让 VPN 服务器可颁发证书供客户端使用。所汇出的档案为 zip 压缩文件,其中包含 ca.crt (VPN 服务器的凭证档案)、openvpn.ovpn (客户端使用的配置文件案),以及 README.txt (客户端如何设定 OpenVPN 联机的简易说明)。
注意:
每次启动 VPN Server 时,便会自动复制、使用显示于控制面板 > 安全性 > 凭证之凭证。若您需使用第三方凭证,请到控制台 > 安全性 > 凭证 > 新增来汇入凭证,并重新启动 VPN Server。
每次修改凭证文件 (显示于控制面板 > 安全性 > 凭证) 后,VPN Server 将会自动重新启动。
L2TP/IPSec
L2TP (Layer 2 Tunneling Protocol) over IPSec 提供更安全的虚拟私有网络,且大多数的客户端 (如 Windows、Mac、Linux 及行动装置) 皆支持。
若要启动 L2TP/IPSec VPN 服务器:
1、开启 VPN Server 并前往左侧面板的 L2TP/IPSec。
2、勾选启动 L2TP/IPSec VPN 服务器。
3、在动态 IP 地址字段输入 VPN 服务器的虚拟 IP 地址。请参阅下方的关于动态 IP 地址来了解更多信息。
4、设定最大联机数量来限制 VPN 联机的共同联机数量。
5、设定同一账号最多联机数量来限制使用同一个账号进行 VPN 联机的共同联机数量。
6、从认证下拉式选单中选择下列任一项目来认证 VPN 客户端:
PAP:认证过程中,将不加密 VPN 客户端的密码。
MS-CHAP v2:认证过程中,将使用 Microsoft CHAP version 2 加密 VPN 客户端的密码。
7、设定 MTU (最大传输单元) 来限制 VPN 网络传输的数据封包大小。
8、勾选手动设定 DNS 并指派 DNS 服务器的 IP 地址来发送给 L2TP/IPSec 客户端。若停用此选项,则会将 Synology NAS 目前所使用的 DNS 服务器发送给客户端。
9、若要发挥 VPN 最大效能,选取执行核心 (kernel) 模式。
10、输入并确认预先共享密钥。您应将此密钥提供给 L2TP/IPSec VPN 使用者以验证联机。
11、勾选启动 SHA2-256 兼容模式 (96 bit),以让特定客户端 (非 RFC 标准) 可以使用 L2TP/IPSec 联机。
12、单击套用来让变更生效。
注意:
联机至 VPN 时,VPN 客户端的验证及加密设定必须与 VPN Server 上的设定相同,否则客户端将无法成功进行联机。
为兼容于运行在 Windows、Mac OS、iOS 与 Android 系统的大部分 L2TP/IPSec 客户端,预设的 MTU 值为 1400。若您的网络环境较为复杂,可能需要设定一个较小的 MTU 值。若您经常收到逾时讯息或联机不稳定,请降低 MTU 值。
请检查 Synology NAS 与路由器上的端口转送规则与防火墙设定,以确认 UDP 1701、500、4500 端口已开启。
部分路由器内建 L2TP 或 IPSec VPN 服务,因此可能已占用 1701、500 或 4500 端口。您需先透过路由器的管理接口关闭其内建的 L2TP 或 IPsec VPN 服务,才能确保 VPN Server 上的 L2TP/IPsec VPN 服务可以正常运作。建议使用支持 VPN pass-through 联机的路由器。
关于动态 IP 地址
VPN Server 会依据您在动态 IP 地址中输入的数字,从虚拟 IP 地址范围中选择一个 IP 地址来分配给 VPN 客户端使用。例如:若 VPN 服务器的动态 IP 地址设定为“10.0.0.0”,则 PPTP VPN 客户端的虚拟 IP 地址范围为“10.0.0.1”至“10.0.0.[最大联机数量]”;OpenVPN 客户端的虚拟 IP 地址范围则为“10.0.0.2”至“10.0.0.255”。
重要事项: 指定 VPN 服务器的动态 IP 地址之前,请注意:
1、VPN 服务器可使用的动态 IP 地址必须为下列其一:
从“10.0.0.0”至“10.255.255.0”
从“172.16.0.0”至“172.31.255.0”
从“192.168.0.0”至“192.168.255.0”
2、您指定的 VPN 服务器动态 IP 地址以及指派给 VPN 客户端的虚拟 IP 地址,皆不能与局域网络中任一已使用的 IP 地址冲突。
关于客户端进行 VPN 联机时使用的网关设定
使用 VPN 联机至 Synology NAS 的局域网络之,客户端可能需要为 VPN 联机变更网关设定;否则,在 VPN 联机建立之后,它们可能会无法联机至因特网。