• vs/nat原理分析


    内核版本:2.6.12

    1.vs/nat原理简介
          
    vs/nat全称visual server /net address translation。通过vs/nat的体系结构如下:

    在一组服务器前有一个调度器(Load Balancer),它们是通过Switch/HUB相连接的。这些服务器提供相同的网络服务、相同的内容,即不管请求被发送到哪一台服务器,执行结果是一样的。服务器Load Balancer被称为虚拟服务器(visual server),对于客户,它的ip地址被称为虚拟ip地址(visual IP address)。下面详细说明一下服务的流程。

    1.客户根据虚拟服务器的虚拟ip地址来发送自己的请求,就是说第一步请求会被发往虚拟服务器;

    2.请求到达虚拟服务器之后,服务器根据调度算法从一组真实的服务器中选出一台服务器,将请求报文的目标地址改成真实服务器的地址。同时虚拟服务器在connection HASH中记录这个连接(连接记录会记录 客户端地址信息、虚拟服务器地址信息以及选定服务器地址信息)。当这个属于这个连接的下一个报文到达时,直接从连接记录中获得选定服务器的地址信息,然后进行同样的改写操作,将数据包发出去。值得注意的是真实服务器的ip地址是属于保留地址172.16.0.0/255.128.0.0的(LVS设定的)。连接记录也是有状态的,当它无效或者超时的时候就从HASH表中将它删除。明显,这一步骤需要一个DNAT操作来把数据包重定位到真实服务器;

    3.真实服务器接到请求后,做相应处理。服务器对客户的回复数据包会发往虚拟服务器;

    4.虚拟服务器收到真实服务器的回复数据包,查找到HASH表中关联的连接记录,然后对数据包做SNAT操作,将数据包的目标地址改写为客户地址;

    5.虚拟服务器将改写好的数据包发往客户;
    对于复杂协议需要额外的处理模块,这和netfilter中是类似的,这里不做额外说明了。

    下面举一个实际的例子来说明一下过程:

    VS/NAT的配置如下表所示,所有到IP地址为202.103.106.5和端口为80的流量都被负载均衡地调度的真实服务器172.16.0.2:80172.16.0.3:8000上。目标地址为202.103.106.5:21的报文被转移到172.16.0.3:21上。而到其他端口的报文将被拒绝。

    Protocol

    Virtual IP Address

    Port

    Real IP Address

    Port

    Weight

    TCP

    202.103.106.5

    80

    172.16.0.2

    80

    1

    172.16.0.3

    8000

    2

    TCP

    202.103.106.5

    21

    172.16.0.3

    21

    1

    访问Web服务的报文可能有以下的源地址和目标地址:

    SOURCE

    202.100.1.2:3456

    DEST

    202.103.106.5:80

    调度器从调度列表中选出一台服务器,例如是172.16.0.3:8000。该报文会被改写为如下地址,并将它发送给选出的服务器。

    SOURCE

    202.100.1.2:3456

    DEST

    172.16.0.3:8000

    从服务器返回到调度器的响应报文如下:

    SOURCE

    172.16.0.3:8000

    DEST

    202.100.1.2:3456

     

    响应报文的源地址会被改写为虚拟服务的地址,再将报文发送给客户:

    SOURCE

    202.103.106.5:80

    DEST

    202.100.1.2:3456

     

    这样,客户认为是从202.103.106.5:80服务得到正确的响应,而不会知道该请求是服务器172.16.0.2还是服务器172.16.0.3处理的。

    2.vs/nat 实现细节
    2.1 vs/natnetfilter中的位置

             vs/nat是基于netfilter框架的,其主要工作在LOACL_IN链和FORWARD链上。

    2.2 代码分析
             vs/nat 没有使用netfilter的连接跟踪机制,而是基于自己的需要,实现了一个自己使用的连接跟踪机制。这个连接跟踪机制和netfilter的连接跟踪机制基本原理是一样的。
    数据结构部分:

    1. ip_vs_service  /*The information about the virtual service offered to the net and the forwarding entries*/

    一个虚拟服务器不止通过一种协议来监听一个端口,它可以监听不同协议上的不同端口的客户请求。可知ip_vs_service便是某个协议的某个端口的一种抽象。

     1 struct ip_vs_service {
     2     struct list_head    s_list;   /* for normal service table */
     3     struct list_head    f_list;   /* for fwmark-based service table */
     4     atomic_t        refcnt;   /* reference counter */
     5     atomic_t        usecnt;   /* use counter */
     6 
     7     __u16            protocol; /* which protocol (TCP/UDP) */
     8     __u32            addr;      /* IP address for virtual service */
     9     __u16            port;      /* port number for the service */
    10     __u32           fwmark;   /* firewall mark of the service */
    11     unsigned        flags;      /* service status flags */
    12     unsigned        timeout;  /* persistent timeout in ticks */
    13     __u32            netmask;  /* grouping granularity */
    14 
    15     struct list_head    destinations;  /* real server d-linked list */
    16     __u32            num_dests;     /* number of servers */
    17     struct ip_vs_stats      stats;         /* statistics for the service */
    18     struct ip_vs_app    *inc;      /* bind conns to this app inc */
    19 
    20     /* for scheduling */
    21     struct ip_vs_scheduler    *scheduler;    /* bound scheduler object */
    22     rwlock_t        sched_lock;    /* lock sched_data */
    23     void            *sched_data;   /* scheduler application data */
    24 };

    ip_vs_service是被存放到两个hash中的,用于不同方向上的快速检索。

    2. ip_vs_conn  /*IP_VS structure allocated for each dynamically scheduled connection */

     1 struct ip_vs_conn {
     2     struct list_head        c_list;         /* hashed list heads *///用于组织成HASH 
     3 
     4     /* Protocol, addresses and port numbers */
     5     __u32                   caddr;          /* client address */
     6     __u32                   vaddr;          /* virtual address */
     7     __u32                   daddr;          /* destination address */
     8     __u16                   cport;          //client端口
     9     __u16                   vport;          //virtual 端口
    10     __u16                   dport;          //destination 端口
    11     __u16                   protocol;       /* Which protocol (TCP/UDP) */
    12 
    13     /* counter and timer */
    14     atomic_t        refcnt;                  /* reference count,引用计数 */
    15     struct timer_list    timer;                /* Expiration timer */
    16     volatile unsigned long    timeout;        /* timeout */
    17 
    18     /* Flags and state transition */
    19     spinlock_t              lock;           /* lock for state transition */
    20     volatile __u16          flags;          /* status flags */
    21     volatile __u16          state;          /* state info, 标识连接状态的*/
    22 
    23     /* Control members */
    24     struct ip_vs_conn       *control;       /* Master control connection /
    25     atomic_t                n_control;      /* Number of controlled ones */
    26     
    27     struct ip_vs_dest       *dest;          /* real server */
    28     atomic_t                in_pkts;      /* incoming packet counter */
    29 
    30     /* packet transmitter for different forwarding methods.  If it
    31        mangles the packet, it must return NF_DROP or better NF_STOLEN,
    32        otherwise this must be changed to a sk_buff **.
    33      */
    34     int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,
    35                struct ip_vs_protocol *pp);
    36 
    37     /* Note: we can group the following members into a structure,
    38        in order to save more space, and the following members are
    39        only used in VS/NAT anyway */
    40     struct ip_vs_app        *app;           /* bound ip_vs_app object */
    41     void                    *app_data;      /* Application private data */
    42     struct ip_vs_seq        in_seq;         /* incoming seq. struct */
    43     struct ip_vs_seq        out_seq;        /* outgoing seq. struct */
    44 };

    连接记录是以hash的方式组织的,与netfilter的连接记录相比,这里的更加简洁一些。

    3.ip_vs_protocol

             这是和协议相关的一个结构体,不同的协议对应它的一个实例,为方便理解,这里直接列举一下tcp协议对应的实例:

     1 struct ip_vs_protocol ip_vs_protocol_tcp = {
     2     .name =            "TCP",
     3     .protocol =        IPPROTO_TCP,
     4     .dont_defrag =        0,
     5     .appcnt =        ATOMIC_INIT(0),
     6     .init =            tcp_init,                 //初始化钩子
     7     .exit =            tcp_exit,
     8     .register_app =        tcp_register_app,
     9     .unregister_app =    tcp_unregister_app,
    10     .conn_schedule =    tcp_conn_schedule,       //函数会根据算法寻找到合适的dest,并新建一个连接记录
    11     
    12     .conn_in_get =        tcp_conn_in_get,    //数据包进入本地时查找连接记录,使用数据包源端信息hash
    13     .conn_out_get =        tcp_conn_out_get,   //转发数据包时查找连接记录,使用数据包目的端信息hash
    14 
    15     .snat_handler =        tcp_snat_handler,   //SNAT操作函数
    16     .dnat_handler =        tcp_dnat_handler,   //DNAT操作函数
    17     .csum_check =        tcp_csum_check,
    18     .state_name =        tcp_state_name,
    19     .state_transition =    tcp_state_transition,
    20     .app_conn_bind =    tcp_app_conn_bind,
    21     .debug_packet =        ip_vs_tcpudp_debug_packet,
    22     .timeout_change =    tcp_timeout_change,
    23     .set_state_timeout =    tcp_set_state_timeout,
    24 };

    流程模拟 :(客户发送新的数据包给虚拟服务器),函数ip_vs_in()图解:



    3.总结

    vs/nat也是利用连接记录来跟踪数据包以完成DNAT的操作的,函数ip_vs_out的原理和ip_vs_in是一样的,就不重复说明了。通过分析,也可以发现vs/nat的实现机制是基于netfilter框架的,而且基本原理上和netfilter的nat实现类似,都是基于连接跟踪的。vs/nat根据自己的需要,实现了另外一个连接跟踪,相比而言,要比netfilter的实现要简单一些,不过这也是因为vs/nat的使用场景的复杂度较低的缘故。vs/nat只负责自己配置的特定协议和端口上的连接跟踪,这是最主要的区别。


  • 相关阅读:
    【Jmeter】他人总结篇链接(共八篇相关文章)
    基于web站点的xss攻击
    【雅思】【绿宝书错词本】List37~48
    【雅思】【绿宝书错词本】List25~36
    【雅思】【绿宝书错词本】List13~24
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/liushaodong/p/2933620.html
Copyright © 2020-2023  润新知