vpn原理及实现--隧道的一种实现

来源:互联网 发布:实现lru算法 编辑:程序博客网 时间:2024/05/16 06:15

理论上已经合理的ip over ssl还需要一些额外的技术支撑才能使用,必须想办法将一个ip数据报原封不动的让它被ssl重新封装一次,这个动作不可能在原始的标准协议栈中执行,标准协议栈不支持数据双向流动,那么解决方案之一就是修改协议栈,在ip层之下实现一个轻量的ssl协议层,但是如此一来就又回到了IPSec的老路上,因此此法不可取,正确的方法是不修改协议栈,让一切留在它应该在的地方,于是ssl必然得在应用层或者说是表示层实现,现在的问题是如何将下层的ip数据报重新引入上面的应用层,而且还不能修改标准协议栈,于是必然地要让ip数据报继续往下走,然后最终从一个网卡流出,于是就出了协议栈,接下来就可以自由发挥了,让数据流出网卡的原因是不能修改协议栈,但是还不能真的让它流出机器,如果它走了就不能指望用ssl封装它了,那么流到哪里呢?回环设备是一个不错的选择,从回环设备流出的数据实际上又流进了回环设备,用户空间只需要打开回环设备然后读取就可以了,注意不能通过一般套接字读取,毕竟那些数据不是发给我们的,要使用类似抓包的方式进行数据抓取,并且用防火墙禁止被抓取的数据继续被forward,这实际上是一种巧妙的拦截方式,被抓取得数据然后经过ssl封装后再发向一个真的ip地址,我们需要配置的就是将所有的vpn数据全部发往回环设备,其实就是添加一条路由,虚拟网络已经建立,事情到此为止看似要结束了。
     但是且慢,问题来了,以后所有vpn数据都会经标准协议栈流出再流进loopback,然后作为裸数据进入应用层,接着整个原始vpn数据连同它的原始ip头封装作为应用数据接受ssl协议的封装,然后发往vpn的另一端,在另一端数据从真实网卡进入,然后由于这是隧道的终点,数据直接进入应用层,在应用层,vpn服务器等候在那里,得到原始的vpn裸数据还有它在发送端的ip头,服务端得到这个东西有什么用呢,接下来它要怎么做呢,它只是隧道的终点,并不是真的要接收数据的机器,因此它必须将数据重新发到真正需要它的机器,很显然它要作为一个应用层代理存在,剥去原始的ip头,得到原始的数据,然后将数据发给真实的目的地,且不说此法是否可能,有两点不合理之处足以否定它,由于vpn服务器实现了代理,那么数据必然要在该处集中并剥去ip头,并且在相反的方向要做同样的处理,那么它就要记住所有的ip头,否则数据就会有去无回,如此一来,vpn服务器的负载可堪忍受?性能呢?第二点,代理的方式消除了隧道的透明性,目的地受到数据后会不知道数据从何而来,统一认为是vpn服务器发来的,这样就无法根据数据源点进行策略化服务。综上原因,loopback设备可用但不可行,因为它是本机闭合的,也就是说只有loopback出去的数据才能进入loopback,它又且仅有两个出口,一读一写都在应用层,你无法将数据作为物理层的流写入loopback,而只能作为应用层的数据通过协议栈逐级封装到达loopback,然后再逐级解封回来,vpn发送端面临同样的问题,因为仅仅是路由将数据出口指向了loopback, 如果不用抓包的方式(pcap)的话是得不到数据的,而这种方式又十分影响性能,加之还要配置复杂的防火墙规则禁止进入loopback的数据被转发,性能又受影响,隧道两端由于是全双工通信,因此一端面临的问题在数据反向时在对端同样存在,抛开这些不谈,仅就loopback无法自由配置ip地址这一条,它就不能被选中来实现隧道,vpn网络需要被管理,有时管理本身就很复杂,虚拟网络不仅仅就一张,我们需要为每张虚拟网络准备一个子网,也就是每个虚拟网络要有不同的ip,所以必然需要灵活的ip配置,故而loopback不能实现优雅透明的隧道,既然如此我们回到原点,无非就是做到两点,第一,数据必须按照协议栈的标准逐级封装和解封装,不能修改协议栈,第二就是数据到了最下面物理层的时候不能真的走掉,而是回到用户空间,于是乎虚拟网卡就成了很好的选择。

原创粉丝点击