Welcome 微信登录

首页 / 操作系统 / Linux / Linux平台VPN技术概论

声明:

1.对于IPSec,不谈其Tunnel以及Transport模式
2.对于OpenVPN,不剖析代码
3.不涉及Linux内核源码剖析
4.不深入谈PPTP以及L2TP
5.本文不是HOWTO也不是技术文档
6.本文的性质是科普

第一部分.VPN要解决的问题以及方案

 

一.问题及方案

基于主机的第三层vpn的要旨就是“透明/安全的接入”,其中透明的含义就是配置要简单,尽量让用户感觉不到vpn的存在,因此这种vpn的实现其实只要解决两个问题即可:
1.如何拿到第N层数据,然后放回第M层;
2.加密/解密第三层ip数据报;

针对第一个问题,实际上我们依赖的是这样一个事实,即OSI的分层网络模型,这样才可以使第M层将第N层的PDU当成有效载荷,解析时只需要根据下层的协议号就可以定位上一层的协议类型。以封装第三层数据的VPN为例,上述第一个问题在linux上有三种方案:

1.使用netfilter

使用netfilter无疑是最直接的方式,对于接收的包,需要在prerouting上挂载一个钩子,对于本地发出的包,则需要在output上挂载一个钩子,这样就可以在钩子函数中进行加密/解密处理了,处理完毕之后再根据策略封装成一个新的ip数据报,重新路由并且发送出去或者接收。

2.使用虚拟网卡

这是一种不直接但是很自然的方式,因为,我们知道从网卡出来的包一个包含一个IP数据报(暂不考虑其它三层协议,比如ipx)。实现一个虚拟网卡,在其xmit发送函数中处理加密,然后重新封装,重新路由。这里暂时先不考虑在哪里解密,因为网卡发送和接收的逻辑是不一样的,我们可以实现一个虚拟网卡,然而却不能修改ip协议栈,除非使用netfilter。

3.将IP数据报导出到用户态,比如使用packet套结字以及替换send/recv

这是最灵活的方案,然而如果使用packet的话却不行。因为packet无法截获数据报。因此需要在socket层次替换send/recv函数,实现加密/封装以及解密/解封装。这里暂时不考虑send处理,因为对于一般的应用数据,是很难替换send的(Linux没有windows的LSP机制),这种方式,控制接收较方便,而控制发送则很难,和使用虚拟网卡的情形正好相反。

我们发现,2和3是互补的,虚拟网卡很容易拿到发出的未封装的原始IP数据报-通过路由即可,但是拿不到接收的封装过的IP数据报,而替换socket的send/recv则很容易拿到接收的封装过的IP数据报但是拿不到发送的未封装的IP数据报。因此将2和3结合一下,就出现了第四种方式。接下来我们来讨论vpn整体的设计。在架设vpn的时候,首先要明白三件事:
1.确定不安全通路的两个端点。我们就在这两个端点之间建立vpn通路;
2.要考虑到对forward数据包的支持,否则就没有必要使用三层vpn了,使用应用层vpn即可。
3.隧道的概念。隧道其实就是vpn链路两个端点之间的加密通路,其中封装着加密后的原始IP数据报。

确定了vpn链路的端点以后,就可以根据上述的3种方式进行加密/封装,解密/解封装的操作了,也就是说,修建一条隧道。具体的方案如下:

方案1:采用netfilter的方式

这种方案部署起来比较简单,因为端点的两台设备是对称的,netfilter钩子会处理IPSec协议逻辑。成型的项目有Freeswan等,具体细节参见《FreeSWAN 结构框架》。

方案2:虚拟网卡+udp

这种方案在端点两端的加密/封装,解密/解封装是不对称的,其中加密/封装这步操作在虚拟网卡完成,解密在recv逻辑中完成,解封装在send逻辑中完成。成型的项目如cipe等。数据通路实际上就是虚拟网卡的方式和导出到用户态方式的结合
设计要点:
1.VPN隧道终点使用UDP端口区分了不同的IP安全通道,而不需要采用IPSec的方式;
2.为何不用TCP呢?因为会引起重传叠加导致网络不可用,详见CIPE的作者所做:《Why TCP Over TCP Is A Bad Idea》。同样的规则在后续的OpenVPN中依然如此,详见OpenVPN的man手册中的--proto选项。
3.加密在内核态,解密在用户态-使用UDP,之所以这样的不对称法是因为UDP端口是可以从客户端“连接(访问的含义)”的,不同的UDP端口就可以区分出来自不同地点的IP安全通道。这种方案依赖于,安全隧道总是由外部(位置不确定的互联网的任意一处)先发起建立请求。后面的OpenVPN的C/S模型也有赖于这个事实。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 下一页
Linux的Netfilter框架深度思考-对比Cisco的ACLLinux知识:操作系统内核子系统的协调工作相关资讯      Linux平台 
  • 停止那些无聊的预测吧!Linux已经  (08/03/2014 09:37:01)
  • Linux平台存储架构与应用方案研究  (04/30/2013 07:03:08)
  • Linux平台用C++实现事件对象,同步  (12/18/2011 19:52:29)
  • Linux 平台七大桌面环境通览  (06/25/2014 12:32:36)
  • 卡马克认为Linux仍然不是一个商业  (08/06/2012 06:49:31)
  • Linux平台上用C++实现多线程互斥锁  (12/18/2011 19:46:15)
本文评论 查看全部评论 (0)
表情: 姓名: 字数