Welcome 微信登录

首页 / 操作系统 / Linux / OpenVPN的按需连接实现

上帝按照自己的形象,造出了人,人按照自己的喜好,造出了计算机,计算机也都有心跳。操作系统靠时钟中断这种心跳来推进机器的时间,然而后来Linux实现了NOHZ,即没有事情的时候,不再无谓地触发时钟中断,而是彻底halt,有事请来的时候,其它的中断会将机器唤醒,继续心跳。这种nohz机制节省了资源,最小化了bug触发率。IPSec VPN完全是按需连接的,隧道模式下,如果数据包过来,匹配到了加密策略,那么就看加密隧道有没有建立,如果还没有建立,则触发IKE协商,如果已经建立了,则直接通过隧道传输数据,当然IPSec也可以使用万恶的心跳...心跳保持的VPN长连接有几个问题,第一,如果收不到心跳,隧道就要被迫断开一次,这种断开事件会被审计为一次异常事件,因为按照正常看来,既然要保持长连接,那它就不应该断开,现在断开了,那是不应该的。第二,对于那种带宽属于稀缺资源的环境,心跳报文会占用可观的资源,比如3G用户,在没有实际数据传输的情况下,发送的心跳报文将是完全的浪费。VPN为何要保持长连接呢?难道随用随连不好吗?隧道的长连接难道仅仅为了展示自己是一个基础设施吗?对于网到网拓扑来讲,这可能是真实的,但是对于终端用户而言,长连接基础设施反而意味着压力,因为终端用户要为心跳报文买单。OpenVPN是一种高度灵活的VPN,它的灵活性以及好处在于你如何使它和外界关联配合,而不在于它本身!记住这一点非常重要!OpenVPN也可以实现按需连接,即没有数据的时候隧道断开,有数据来的时候创建隧道,并且在持续一段时间没有数据的时候再次断开隧道。这些事件中,除了”持续一段时间没有数据的时候再次断开隧道“这个功能(--inactive参数)是OpenVPN本身的功能外,其它的都需要外部的协助,首先我们要考虑的是,如何按需创建连接。通过iptables识别什么是”需要通过OpenVPN加密传输“的数据,识别到了以后,必须”堵住“该数据,直到隧道建立后再将它放行,堵在哪里呢?当然是堵在队列里面,如果隧道建立的时间比较久,那队列无疑会满掉,此时丢弃新来者是迫不得已的行为。有了此大方向,接下来就是具体的方案。在Linux上,几乎什么东西都不需要自己重做,以上这个功能可以通过iptables的QUEUE来实现,该target将数据包queue,用户态进程read这些排队的数据包到用户态,然后...然后该进程可以直接将包重新注入回内核,也可以在注入之前先去建立OpenVPN隧道,隧道建立以后再注入数据包,既然此时隧道已经建立了,路由规则该添加的也添加了,那么后续的数据包就不需要再QUEUE到用户态了,这个又是怎么实现的呢?还好,Netfilter有一个addons扩展,扩充了iptables的功能,我们需要的就是一个叫做condition的模块,该模块的使用使得多条iptables规则之间可以完成很多复杂的控制逻辑,如下一条:iptables -t mangle  -A PREROUTING -d 192.168.1.1/32 -m condition --condition "vpn"  -j QUEUE它的意思就是只有在vpn这个condition变量的值为1的时候,发往192.168.1.1的数据包才会去排队,否则就直接匹配下一条规则,不会被排队。到此为止,所有的准备工作基本就绪,剩余的工作即是如何把这一切拼接在一起形成方案。为了快速说明问题,我就不再使用OpenVPN举例了,我用一种等价的方式说明问题:只有当到达192.168.1.1的数据包来的时候才建立其明细路由,持续没有到达192.168.1.1的流量5秒钟后删掉该明细路由。这个足以说明问题了,它足够简单。虽然说即使它这么简单,最终还还是偷了懒,没有实现完全。首先添加上面列举的那条iptables规则,然后创建一个用户态进程,代码如下:#include <linux/netfilter.h>
#include <string.h>
#include <stdlib.h>
#include <libipq.h>
#include <stdio.h>
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <linux/ip.h>
#include <signal.h>#define BUFSIZE 2048
static int condition = 0;void condition_handler(int num)
{
        if (condition == 1) {
                condition = 0;
        } else {
                condition = 1;
        }
}int main(int argc, char **argv)
{
        int status;
        unsigned char buf[BUFSIZE];
        struct ipq_handle *h;
        signal (SIGUSR1, condition_handler);
        h = ipq_create_handle(0, 2/*PROTO_IPV4*/);
        status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
        do{
                status = ipq_read(h, buf, BUFSIZE, 0);
                switch (ipq_message_type(buf)) {
                case IPQM_PACKET: {
                        ipq_packet_msg_t *m = ipq_get_packet(buf);
                        size_t data_len = m->data_len;
                      //读取到有数据包后,触发执行启动VPN脚本的命令
                        system("/home/zhaoya/start_vpn param1 param2 paramX");
                      //等待start_vpn命令执行完毕,它会建立VPN隧道,建立完成发送信号给该进程
                        while(!condition) {
                                pause();
                        }             
                      //成功建立隧道以后,将数据包原封不动地重新注入回去
                        status = ipq_set_verdict(h, m->packet_id,
                                NF_ACCEPT, data_len+sizeof(struct iphdr), (char*)m->payload);
                        break;
                        }
                default:
                        break;
                }
        } while (1);
        ipq_destroy_handle(h);
        return 0;
}更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2013-12/93745p2.htm相关阅读:Ubuntu下OpenVPN客户端配置教程 http://www.linuxidc.com/Linux/2013-06/86562.htmUbuntu 10.04搭建OpenVPN http://www.linuxidc.com/Linux/2012-11/74790.htmUbuntu 13.04 VPN (OpenVPN) 配置和连接不能同时访问内外网的问题 http://www.linuxidc.com/Linux/2013-07/86899.htm如何在Linux上用OpenVPN搭建安全的远程网络架构 http://www.linuxidc.com/Linux/2013-11/92646.htmOpenVPN 的详细介绍:请点这里
OpenVPN 的下载地址:请点这里
  • 1
  • 2
  • 下一页
Linux下使用虚拟网卡的ingress流控(入口流控)Linux下tmpfs介绍及使用相关资讯      openvpn 
  • 如何使用OpenVPN和PrivacyIDEA搭建  (01月18日)
  • OpenVPN异地机房互连以及负载均衡  (07/23/2015 13:19:11)
  • 单独一台机器测试OpenVPN加密隧道  (01/12/2015 07:11:41)
  • 在 Ubuntu 15.04 上安装配置   (08/03/2015 11:08:56)
  • CentOS6.5 Linux基于AD域账号联动  (06/20/2015 07:47:40)
  • Android上的OpenVPN-TAP模式/策略  (12/21/2014 12:50:48)
本文评论 查看全部评论 (0)
表情: 姓名: 字数