<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [ipsec][strongswan] strongswan源碼分析--(一)SA整體分析

      strongswan SA分析(一)

      1 概念

      下面主要介紹兩個本文將要闡述的核心概念。他們是SA和SP。注意,這不是一篇不需要背景知識的文章。作者認為你適合閱讀接下來內容的的前提是,你已經具備了一下三方面的知識:

      • a. 什么是VPN。
      • b. 什么是IPsec,包括IKE,ESP,strongswan都是什么等。
      • c. 一般的linux使用方法和常見概念。

      1.1 什么是SAD,SPD

      SAD是Security Association Database的縮寫。
      SPD是Security Policy Database的縮寫。
      SAD是用來存儲SA的數據庫。SPD是用來存儲SP的數據庫。

      1.2 什么是SPI

      SPI是Security Parameter Index的縮寫。是有一組數字(長度?)。被使用在SAD和SPD里作為索引的一部分。是由IKE協商的兩側客戶端隨機選擇的UUID?。0-255是被保留的值,禁止在SPI中使用。

      1.3 什么是SA

      SA是Security Association的縮寫。SA是一組算法和算法參數(包括key)的集合,用來完成單個方向的數據流加密和驗證任務。通過SPI加數據包的目的地址可以唯一查找到一個SA。

      包含的屬性:

      • 加密算法
        • 屬性
        • key
      • 驗證算法
        • 屬性
        • key
      • SPI
      • 目的地址

      1.4 什么是SP

      SP是Security Policy的縮寫。SP是一條規則,決定一條流(flow)是否需要被IPsec處理。SP的處理有三種方式:

      • 丟棄
      • 不處理
      • 處理

      需要被IPsec處理的流,會被指向到一個template。一個template可以理解為指向一個SA,template包含以下屬性:

      • 協議
        • AH或ESP。
      • 模式
        • transport或tunnel模式。
      • pattern
        • 源IP加目的IP對。
        • NAT的PORT對。

      SP有一個方向屬性,取值分別為:

      • out
      • in
      • fwd

      1.5 總結

      在整個IPsec的數據流轉邏輯中,SP用來表達What todo。SA用來表達How todo。


      2 數據流

      簡單的說。明文報在通過IPsec VPN設備變成ESP發出去的過程是:

      1. 查找路由。
      2. 查找policy決定是否需要被ESP
      3. 查找SA并加密封裝。
      4. 加密封裝后的包再查路由。

      IPsec報在通過IPsec VPN設備變成非加密包發出去的過程:

      1. 查找路由。
      2. 查找policy決定是否需要要解ESP
      3. 查找SA并解密解封裝。
      4. 解密解封裝后的包再查路由。

      flow.png

      2.1 舉個栗子

      路由

      [root@T9 sbin]# ip route
      default via 192.168.7.1 dev eth0  proto static  metric 100 
      10.129.0.0/24 dev eth1  proto kernel  scope link  src 10.129.0.1  metric 100 
      192.168.7.0/24 dev eth0  proto kernel  scope link  src 192.168.7.129  metric 100 
      

      policy

      [root@T9 sbin]# ip xfrm policy
      src 10.9.0.0/16 dst 10.129.0.0/16 
      	dir fwd priority 383616 ptype main 
      	tmpl src 192.168.7.9 dst 192.168.7.129
      		proto esp reqid 1 mode tunnel
      src 10.9.0.0/16 dst 10.129.0.0/16 
      	dir in priority 383616 ptype main 
      	tmpl src 192.168.7.9 dst 192.168.7.129
      		proto esp reqid 1 mode tunnel
      src 10.129.0.0/16 dst 10.9.0.0/16 
      	dir out priority 383616 ptype main 
      	tmpl src 192.168.7.129 dst 192.168.7.9
      		proto esp reqid 1 mode tunnel
      

      sa

      [root@T9 sbin]# ip xfrm state
      src 192.168.7.129 dst 192.168.7.9
      	proto esp spi 0xc42ac7f3 reqid 1 mode tunnel
      	replay-window 0 flag af-unspec
      	auth-trunc hmac(sha256) 0x5f7b99e.....eb20948fb2f8fc713caf2d43b4 128
      	enc cbc(aes) 0x48144872d5f4f9a6a762b68785e6f265
      src 192.168.7.9 dst 192.168.7.129
      	proto esp spi 0xc1c8ad99 reqid 1 mode tunnel
      	replay-window 32 flag af-unspec
      	auth-trunc hmac(sha256) 0x7efc5d2172.....0c0dedf053b0b6ae5aa2f012 128
      	enc cbc(aes) 0x808efcfaa45a543b69efe08158accaa3
      

      3 理解linux kernel中的sa概念和管理

      3.1 提供給用戶的sa接口

      理解kernel sa對用戶展示的形態,可以幫助我們理解linux kernel對于ipsec sa的建模和抽象。對我們在VPN產品的sa模塊設計中將提供幫助。

      3.1.1 使用racoon配置sa

      setkey add 192.168.0.1 192.168.1.2 esp 0x10001
              -m tunnel
              -E des-cbc 0x3ffe05014819ffff
              -A hmac-md5 "authentication!!"
      

      從以上信息可以很容易開始各個參數表達的含義,其中-E代表加密算法和它的key,-A代表驗證算法和它的key。0x10001為spi。

      3.1.2 使用racoon配置policy

      setkey spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any
              -P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require
      

      第一行代表五元組,any代表協議。第二行代表policy的具體描述:方向,action,template。

      3.1.3 總結

      通過以上兩個小節的描述,讀者應該已經很容易的總結出了配置一個SA和一個policy所需要提供的最基本的信息了。作者將在本章的最后,對sa和poliyc所包含的所有必須信息進行一個統一的總結。
      另外,通過上文的語法,我們應該能夠發現,policy與sa之間的match操作,是需要一個稍負責的匹配邏輯來實現的,而不僅僅是一個簡單的匹配關系。

      3.2 netlink的SA接口

      strongswan是目前使用兩種方式與內核進行ipsec的配置交互,分別為netlink和pfkey。如官方文檔所述,netlink是strongswan默認啟用的,變成stable的接口方式。整個調研工作也是以netlink方式為出發點展開的,現簡單介紹如下。

      netlink是復用了socket方式的內核與用戶態IPC方法。
      這里有一篇寫的非常好的文章,講netlink為什么會產生。由于人家寫的實在是太好了,我已經沒有什么可寫的了,只能做個概要,如下:
      netlink.jpeg
      因為作者圖畫是業余的,所以看懂的這個概要圖的前提是,你必須懂得BSD socket的api如何使用。

      3.2.2 接口方式

      用netlink方式配置ipsec的方法。

      netlink的一般用法
      初始化socket

      與常規的socket用法相同,只是傳入參數是netlink定義的特有參數。

      int socket(int domain, int type, int protocol)
      bind(fd, (struct sockaddr*)&nladdr, sizeof(nladdr));
      
      下發配置信息到kernel

      使用socket的標準send,write接口將特定格式的參數下發給kernel。
      參數格式如下:

      struct nlmsghdr
      {
        __u32 nlmsg_len;   /* Length of message */
        __u16 nlmsg_type;  /* Message type*/
        __u16 nlmsg_flags; /* Additional flags */
        __u32 nlmsg_seq;   /* Sequence number */
        __u32 nlmsg_pid;   /* Sending process PID */
      };
      

      這個參數結構體是傳入參數的頭部,緊接著這個頭部之后的內存是真正的參數的值。它的解析方法由nlmsg_type的值來確定。它的結尾由nlmsg_len的數值來決定。

      添加sa

      添加sa的時候,nlmsghdr后面的參數為結構體

      struct xfrm_usersa_info
      

      nlmsg_type的值為:XFRM_MSG_NEWSA
      這部分內容定義在系統文件下:

      /usr/include/linux/xfrm.h
      

      這個結構體后邊,還需要追加算法部分的信息,如下:

      struct xfrm_algo
      struct xfrm_algo_auth
      
      添加policy

      添加policy的時候,nlmsghdr后面的參數為結構體

      struct xfrm_userpolicy_info
      

      nlmsg_type的值為:XFRM_MSG_NEWPOLICY
      這部分內容定義在系統文件下:

      /usr/include/linux/xfrm.h
      

      3.3 xfrm的SA接口

      3.3.1 什么是xfrm

      xfrm(transform)是一個IP包轉發框架。主要實現以下三部分功能:

      • IPsec protocol suite
      • IP Payload Compression Protocol
      • Mobile IPv6

      3.3.2 內核代碼

      linux/net/xfrm/
      

      主要函數

      Xfrm_lookup()            xfrm lookup(SPD and SAD) method
      Xfrm_input()             xfrm processing for an ingress packet
      Xfrm_output()            xfrm processing for an egress packet
      Xfrm4_rcv()              IPv4 specific Rx method
      Xfrm6_rcv()              IPv6 specific Rx method
      Esp_input()              ESP processing for an ingress packet
      Esp_output()             ESP processing for an egress packet
      Ah_output()              AH processing for an ingress packet
      Ah_input()               ESP processing for an egress packet
      xfrm_policy_alloc()      allocates an SPD object
      Xfrm_policy_destroy()    frees an SPD object
      xfrm_ policy_lookup      SPD lookup
      xfrm_policy_byid()       SPD lookup based on id
      Xfrm_policy_insert()     Add an entry to SPD
      Xfrm_Policy_delete()     remove an entry from SPD
      Xfrm_bundle_create()     creates a xfrm bundle
      Xfrm_policy_delete()     releases the resources of a policy object
      Xfrm_state_add()         add an entry to SAD
      Xfrm_state_delete()      free and SAD object
      Xfrm_state_alloc()       allocate an SAD object
      xfrm_state_lookup_byaddr()     src address based SAD lookup
      xfrm_state_find()        SAD look up based on dst
      xfrm_state_lookup()      SAD lookup based on spi
      

      3.3.3 API

      api文件

      include/uapi/linux/xfrm.h
      

      主要的API

      XFRM_MSG_NEWSA         To add a new SA to SAD
      XFRM_MSG_DELSA         To delete a new SA to SAD
      XFRM_MSG_GETSA         To get a new SA to SAD
      XFRM_MSG_FLUSHSA       To flush SAD
      XFRM_MSG_NEWPOLICY     To add a new policy to SPD
      XFRM_MSG_DELPOLICY     To delete a new policy to SPD
      XFRM_MSG_GETPOLICY     To get a new policy to SPD
      XFRM_MSG_FLUSHPOLICY   To flush SPD
      

      3.3.4 sa的傳入參數

      struct xfrm_usersa_info {
              struct xfrm_selector            sel; // 被加密網段?為啥要有這個?
              struct xfrm_id                  id; // 目的ip,spi,協議ah/esp
              xfrm_address_t                  saddr; // 源ip
              struct xfrm_lifetime_cfg        lft;
              struct xfrm_lifetime_cur        curlft;
              struct xfrm_stats               stats;
              __u32                           seq;
              __u32                           reqid;
              __u16                           family;
              __u8                            mode; // transport / tunnel
              __u8                            replay_window;
              __u8                            flags;
      };  
      

      算法參數是追加在SA結構體之后的內存塊,根據不同的類型決定不同的結構。示例:

      struct xfrm_algo {
              char            alg_name[64];
              unsigned int    alg_key_len;    /* in bits */
              char            alg_key[0];
      };
      
      struct xfrm_algo_auth {
              char            alg_name[64];
              unsigned int    alg_key_len;    /* in bits */
              unsigned int    alg_trunc_len;  /* in bits */
              char            alg_key[0];
      };
      

      3.3.5 policy的傳入參數

      struct xfrm_userpolicy_info {
              struct xfrm_selector            sel; //網段:ip,port,協議
              struct xfrm_lifetime_cfg        lft;
              struct xfrm_lifetime_cur        curlft;
              __u32                           priority; //
              __u32                           index;
              __u8                            dir;  //方向:in out fwd
              __u8                            action; // allow, block
              __u8                            flags;
              __u8                            share;
      };
      

      4 xfrm的實現

      4.1 用于存儲sa的內部數據結構

      struct xfrm_state {
      #ifdef CONFIG_NET_NS
              struct net              *xs_net;
      #endif
              union {
                      struct hlist_node       gclist;
                      struct hlist_node       bydst;
              };
              struct hlist_node       bysrc;
              struct hlist_node       byspi; 
              atomic_t                refcnt;
              spinlock_t              lock;
              struct xfrm_id          id;
              struct xfrm_selector    sel;
              struct xfrm_mark        mark;
              u32                     tfcpad;
              u32                     genid;
              /* Key manager bits */
              struct xfrm_state_walk  km;
              /* Parameters of this state. */
              struct {
                      u32             reqid;
                      u8              mode;
                      u8              replay_window;
                      u8              aalgo, ealgo, calgo;
                      u8              flags;
                      u16             family;
                      xfrm_address_t  saddr; 
                      int             header_len;
                      int             trailer_len;
                      u32             extra_flags;
              } props;
              struct xfrm_lifetime_cfg lft;
              /* Data for transformer */
              struct xfrm_algo_auth   *aalg;
              struct xfrm_algo        *ealg;
              struct xfrm_algo        *calg;
              struct xfrm_algo_aead   *aead;
              /* Data for encapsulator */
              struct xfrm_encap_tmpl  *encap;
              /* Data for care-of address */
              xfrm_address_t  *coaddr; 
                      /* IPComp needs an IPIP tunnel for handling uncompressed packets */
              struct xfrm_state       *tunnel;
              /* If a tunnel, number of users + 1 */
              atomic_t                tunnel_users;
              /* State for replay detection */
              struct xfrm_replay_state replay;
              struct xfrm_replay_state_esn *replay_esn;
              /* Replay detection state at the time we sent the last notification */  
              struct xfrm_replay_state preplay;
              struct xfrm_replay_state_esn *preplay_esn;
              /* The functions for replay detection. */
              struct xfrm_replay      *repl;
              /* internal flag that only holds state for delayed aevent at the
               * moment
              */
              u32                     xflags;
              /* Replay detection notification settings */
              u32                     replay_maxage;
              u32                     replay_maxdiff;
              /* Replay detection notification timer */
              struct timer_list       rtimer;
              /* Statistics */
              struct xfrm_stats       stats;
              struct xfrm_lifetime_cur curlft;
              struct tasklet_hrtimer  mtimer;
              /* used to fix curlft->add_time when changing date */
              long            saved_tmo;
              /* Last used time */
              unsigned long           lastused;
              /* Reference to data common to all the instances of this
               * transformer. */
              const struct xfrm_type  *type;
              struct xfrm_mode        *inner_mode;
              struct xfrm_mode        *inner_mode_iaf;
              struct xfrm_mode        *outer_mode;
              /* Security context */
              struct xfrm_sec_ctx     *security;
              /* Private data of this transformer, format is opaque,
               * interpreted by xfrm_type methods. */
              void                    *data;
      };
      

      會被插入兩個hash表

         1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
         2. Hash table by (daddr,family,reqid) to find what SAs exist for given
            destination/tunnel endpoint. (output)
      

      4.2 用于存儲sa的內部數據結構

      struct xfrm_policy {
      #ifdef CONFIG_NET_NS
              struct net              *xp_net;
      #endif
              struct hlist_node       bydst; 
              struct hlist_node       byidx;
              /* This lock only affects elements except for entry. */
              rwlock_t                lock;
              atomic_t                refcnt; 
              struct timer_list       timer;
              struct flow_cache_object flo;
              atomic_t                genid;
              u32                     priority;
              u32                     index;
              struct xfrm_mark        mark;
              struct xfrm_selector    selector;
              struct xfrm_lifetime_cfg lft;
              struct xfrm_lifetime_cur curlft;
              struct xfrm_policy_walk_entry walk;
              struct xfrm_policy_queue polq;
              u8                      type;
              u8                      action;
              u8                      flags;
              u8                      xfrm_nr;
              u16                     family;
              struct xfrm_sec_ctx     *security;
              struct xfrm_tmpl        xfrm_vec[XFRM_MAX_DEPTH];
      };        
      

      4.3 數據結構之間的存儲結構

      TODO

      4.4 關鍵函數

      xfrm_lookup()
      xfrm_output()
      xfrm4_policy_check() // 在ipv4中被調用。
      

      5 strongswan中的sa

      5.1 概述

      從IKE協議的角度上,有兩個SA,一個叫IKE_SA,一個叫CHILD_SA。本章討論的sa,特指下圖中的CHILD_SA。
      本篇文章,通篇討論的SA指的都是這里的CHILD_SA。

      CHILD_SA在strongswan的框架里,主要存在與兩個部分。

      1. IKE協商過程。
        CHILD_SA是IKE協商過程中的輸出。IKE協商過程結束后,IKE-SA Manager將CHILD_SA交個strongswan框架。
      2. IPsec隧道建立過程。
        CHILD_SA是IKE協商過程中的輸入。strongswan框架將CHILD_SA交給libcharon plugin由特定的plugin與kernel通信,在kernel中完成IPsec tunnel的建立過程。
      3. IPsec在轉發過程。
        這部分和strongswan的框架沒有了關系,由內核完成。
            +---------------------------------+       +----------------------------+
            |          Credentials            |       |          Backends          |
            +---------------------------------+       +----------------------------+
      
             +------------+    +-----------+        +------+            +----------+
             |  receiver  |    |           |        |      |  +------+  | CHILD_SA |
             +----+-------+    | Scheduler |        | IKE- |  | IKE- |--+----------+
                  |            |           |        | SA   |--| SA   |  | CHILD_SA |
          +-------+--+         +-----------+        |      |  +------+  +----------+
       <->|  socket  |               |              | Man- |
          +-------+--+         +-----------+        | ager |  +------+  +----------+
                  |            |           |        |      |  | IKE- |--| CHILD_SA |
             +----+-------+    | Processor |--------|      |--| SA   |  +----------+
             |   sender   |    |           |        |      |  +------+
             +------------+    +-----------+        +------+
      
            +---------------------------------+       +----------------------------+
            |               Bus               |       |      Kernel Interface      |
            +---------------------------------+       +----------------------------+
                   |                    |                           |
            +-------------+     +-------------+                     V
            | File-Logger |     |  Sys-Logger |                  //////
            +-------------+     +-------------+
      

      5.1.1 strongswan中的plugin

      上一小節提到了plugin,接下來講解plugin
      有兩類plugins。一類是libstrongswan的plugin,一類是libcharon的plugin
      libstrongswan的plugin主要提供加密,認證,數據庫相關的功能。
      libcharon的plugin主要提供“specific needs”。。。我們接下來要討論的與sa下發相關的plugin都在
      libcharon這一類里。他們包括:

      • kernel-libipsec
        用戶態的轉發平面,目前還處于高實驗性階段。轉發性能沒有kernel。主要用來滿足不能使用kernel轉發的場景。
      • kernel-netlink
        使用netlink接口與linux kernel的xfrm模塊交互。目前輸出穩定使用階段,默認首選。
      • kernel-iph
        windows操作系統的接口。
      • kernel-pfkey
        使用pkkey接口與linux kernel的xfrm模塊進行交互,高實驗性階段。
      • kernel-wfp
        windows操作系統的接口。

      本文,只關心kernel-netlink的plugin。

      5.2 啟動過程

      5.2.1 概述

      strongswan的啟動方式有多種。可以和各種不同的系統對接,包括systemd,networkmanager等。

      • starter
        ipsec命令使用的守護進程。用ipsec start命令,就會啟動這個進程。
      • charon-nm
        networkmanager的plugin。什么是nm的plugin?
      • charon-systemd
        按照systemd的daemon style實現的一個進程。由systemd啟動。
      • charon-svc
        windows的服務。

      各種啟動方式的最終目的都是啟動最終目的都是啟動charon進程。所以,最簡的啟動方法就是:

      • 直接運行charon進程

      當然,這種方式沒有daemon守護,但是功能完整。

      5.2.2 調試方法

      如上一小節所述。charon進程可以直接運行。所以調試的時候直接使用gdb運行charon就可以了。

      # gdb `which charon`
      

      5.2.3 starter的啟動過程

      starter的啟動方法是通過ipsec腳本執行start命令,這樣便啟動了strongswan服務。

      # ipsec start
      
      ipsec腳本

      源碼位置

      strongswan-5.7.1/src/ipsec/_ipsec
      

      ipsec腳本解析start參數后,會執行如下命令,啟動daemon進程starter

      ${IPSEC_DIR}/starter --daemon charon
      
      starter進程

      源碼位置

      strongswan-5.7.1/src/starter/starter.c
      

      starter的主要功能是啟動charon進程,并進行守護。

      • daemon的初始工作
        重定向輸出,signal響應等。
      • 啟動charon
      • 加載ipsec.conf中的配置。
      流程圖

      starter.png

      charon進程

      charon進程運行啟動成功后,啟動16個子線程執行不同的job。
      整個charon中的任務調度圍繞著task和job兩個核心概念進行。

      流程圖

      實線代表流程圖;虛線代表調用棧。
      charon.png

      5.2.4 systemd的啟動過程

      systemd的啟動過程首先使用systemd的service配置腳本。然后啟動systemd的charon守護進程。
      最后通過守護進程啟動charon進程。

      systemd腳本

      源碼位置

      strongswan-5.7.1/init/systemd-swanctl/strongswan-swanctl.service.in
      

      service腳本在啟動過程執行兩個操作。

      1. 啟動charon-systemd進程。
      2. 執行swanctl --load-all --noprompt命令
      charon-systemd進程

      源碼位置

      strongswan-5.7.1/src/charon-systemd/charon-systemd.c
      

      charon-systemd進程是charon進程的另一個入口。charon-systemd進程不會在啟動新的進程,charon-systemed進程就是處理業務的主進程,有systemd進行守護。
      所以,charon-systemd只有main函數中的少量內容與charon不同。其他邏輯與charon進程完全相同。

      流程圖

      charon-systemd.png

      5.3 調用過程

      運行過程中,與SA相關的兩個部分主要就是add_sa與add_policy兩個地方。
      當charon進程收到一個message的時候,會以job的形式分發給standby的業務線程進行處理。
      最后通過kernel對象調用kernel_interface接口中的add_sa和add_policy兩個函數。接口會根據
      具體注冊的plugin調用各plugin的相應,add_as, add_policy函數。

      例如,netlink的plugin。
      在該plugin的這兩個函數中,會通過netlink的接口最終調用內核的xfrm接口完成sa和policy的下發和更新等操作。
      詳見3.2和3.3兩個章節。

      5.4 數據結構

      strongswan中的sa數據結構

      定義在文件 kernel_ipsec.h 中,由id和data兩個結構共同組成。

      struct kernel_ipsec_sa_id_t {
              /** Source address */
              host_t *src;
              /** Destination address */
              host_t *dst;
              /** SPI */
              uint32_t spi;
              /** Protocol (ESP/AH) */
              uint8_t proto;
              /** Optional mark */
              mark_t mark;
      };
      
      /** 
       * Data required to add an SA to the kernel
       */
      struct kernel_ipsec_add_sa_t {
              /** Reqid */
              uint32_t reqid;
              /** Mode (tunnel, transport...) */
              ipsec_mode_t mode;
              /** List of source traffic selectors */
              linked_list_t *src_ts;
              /** List of destination traffic selectors */
              linked_list_t *dst_ts;
              /** Network interface restricting policy */
              char *interface;
              /** Lifetime configuration */
              lifetime_cfg_t *lifetime;
              /** Encryption algorithm */
              uint16_t enc_alg;
              /** Encryption key */
              chunk_t enc_key;
              /** Integrity protection algorithm */
              uint16_t int_alg;
              /** Integrity protection key */
              chunk_t int_key;
              /** Anti-replay window size */
              uint32_t replay_window;
              /** Traffic Flow Confidentiality padding */
              uint32_t tfc;
              /** IPComp transform */
              uint16_t ipcomp;
              /** CPI for IPComp */
              uint16_t cpi;
              /** TRUE to enable UDP encapsulation for NAT traversal */
              bool encap;
              /** no (disabled), yes (enabled), auto (enabled if supported) */
              hw_offload_t hw_offload;
              /** Mark the SA should apply to packets after processing */
              mark_t mark;
              /** TRUE to use Extended Sequence Numbers */
              bool esn;
              /** TRUE to copy the DF bit to the outer IPv4 header in tunnel mode */
              bool copy_df;
              /** TRUE to copy the ECN header field to/from the outer header */
              bool copy_ecn;
              /** Whether to copy the DSCP header field to/from the outer header */
              dscp_copy_t copy_dscp;
              /** TRUE if initiator of the exchange creating the SA */
              bool initiator;
              /** TRUE if this is an inbound SA */
              bool inbound;
              /** TRUE if an SPI has already been allocated for this SA */
              bool update;
      }; 
      

      strongswan中的policy數據結構

      定義在文件 kernel_ipsec.h 和 ipsec_types.h 中。

      struct kernel_ipsec_policy_id_t {
              /** Direction of traffic */
              policy_dir_t dir;
              /** Source traffic selector */
              traffic_selector_t *src_ts;
              /** Destination traffic selector */
              traffic_selector_t *dst_ts;
              /** Optional mark */
              mark_t mark; 
              /** Network interface restricting policy */
              char *interface;
      };
      
      /**
       * Data required to add/delete a policy to/from the kernel
       */
      struct kernel_ipsec_manage_policy_t {
              /** Type of policy */
              policy_type_t type;
              /** Priority class */
              policy_priority_t prio;
              /** Manually-set priority (automatic if set to 0) */
              uint32_t manual_prio;
              /** Source address of the SA(s) tied to this policy */
              host_t *src;
              /** Destination address of the SA(s) tied to this policy */
              host_t *dst;
              /** Details about the SA(s) tied to this policy */
              ipsec_sa_cfg_t *sa;
      };
      
      struct ipsec_sa_cfg_t {
          /** mode of SA (tunnel, transport) */
          ipsec_mode_t mode;
          /** unique ID */
          uint32_t reqid;
          /** number of policies of the same kind (in/out/fwd) attached to SA */
          uint32_t policy_count;
          /** details about ESP/AH */
          struct {
              /** TRUE if this protocol is used */
              bool use;
              /** SPI for ESP/AH */
              uint32_t spi;
          } esp, ah;
          /** details about IPComp */
          struct {
              /** the IPComp transform used */
              uint16_t transform;
              /** CPI for IPComp */
              uint16_t cpi;
          } ipcomp;
      };
      

      6 sa的抽象模型

      6.1 實現sa管理的思路

      略。

      6.2 sa

      目的地址(dip)加 spi 唯一確定一個sa條目。

      屬性 取值 說明
      id
      spi 協商過程帶過來的
      mode transport/tunnel
      protocol esp/ah/ipcom 加密協議的方式
      sip 另一條隧道是sip和dip互換的,故兩個sa
      dip
      life 生存時間
      enc_alg
      enc_key
      integrity_alg 完整性驗證
      integrity_key
      nat 是否做nat

      6.3 policy

      屬性 取值 說明
      id
      action drop/pass/ipsec 命中此策略后的行為
      priority 優先級
      dir in/out/fwd 方向
      s_ts source traffic selector
      d_ts destination traffic selector

      6.4 traffic selector

      ts就是五元組,ip使用掩碼掩起來的一個段。port也可以掩,具體跟kernel學一下。

      屬性 說明
      source ip
      sip_prefixlen
      dest ip
      dip_prefixlen
      sport
      sport_mask
      dport
      dport_mask
      protocol

      7 問題

      7.1 policy與路由的關系

      在我的測試虛機環境里,刪掉了策略路由之后,功能正常。
      目前還不清楚為什么。路由與policy之間的關系,以及路由和policy在內核包轉發過程中的邏輯關系,
      都需要進一步的調研。

      7.2 policy與sa之間的關聯邏輯


      參考

      http://man7.org/linux/man-pages/man8/ip-xfrm.8.html

      posted on 2019-08-17 22:58  toong  閱讀(15046)  評論(2)    收藏  舉報

      主站蜘蛛池模板: 国产成人精品午夜二三区| 亚洲精中文字幕二区三区| 欧美成本人视频免费播放| 福利一区二区在线视频| 国产情侣激情在线对白| 亚洲日本韩国欧美云霸高清| 国产精品爽爽久久久久久竹菊| 日本丰满少妇高潮呻吟| 国产欧美亚洲精品第1页| 高清精品一区二区三区| 国产精品一区二区色综合| 欧美乱妇高清无乱码免费| 国产睡熟迷奷系列网站| 动漫AV纯肉无码AV电影网| 国产成人不卡无码免费视频| 大尺度国产一区二区视频| 女人高潮被爽到呻吟在线观看| 强奷白丝美女在线观看| 国产精品永久在线观看| 日韩一区二区三区亚洲一| 无码国产偷倩在线播放| 国产又黄又爽又刺激的免费网址| 岛国最新亚洲伦理成人| 又黄又刺激又黄又舒服| 久热这里只有精品视频六| 无码免费大香伊蕉在人线国产| 日韩精品中文字幕人妻| 亚洲av无码一区二区三区网站| 日韩乱码人妻无码中文字幕 | 亚洲最大的成人网站| 无码人妻一区二区三区在线视频| 日本中文字幕在线播放| 男女性高爱潮免费网站| 亚洲国产片一区二区三区| 成人亚欧欧美激情在线观看| 在线 国产 欧美 专区| 国产精品aⅴ免费视频| 乱人伦人妻中文字幕不卡| 欧洲精品码一区二区三区| 马龙县| 午夜国产理论大片高清|