当前位置:   article > 正文

XFRM -- ipsec协议的内核实现框架

xfrm

目录

1 Overview

1.1 XFRM 实例

1.2 Netlink 通道

1.3 XFRM State

1.3 XFRM Policy

2 接收发送IPsec报文

2.1 接收

2.2 发送


IPsec协议帮助IP层建立安全可信的数据包传输通道。当前已经有了如StrongSwanOpenSwan等比较成熟的解决方案,而它们都使用了Linux内核中的XFRM框架进行报文接收发送。

XFRM的正确读音是transform(转换), 这表示内核协议栈收到的IPsec报文需要经过转换才能还原为原始报文;同样地,要发送的原始报文也需要转换为IPsec报文才能发送出去。

1 Overview

1.1 XFRM 实例

IPsec中有两个重要概念:安全关联(Security Association)和安全策略(Security Policy),这两类信息都需要存放在内核XFRM。核XFRM使用netns_xfrm这个结构来组织这些信息,它也被称为xfrm instance(实例)。从它的名字也可以看出来,这个实例是与network namespace相关的,每个命名空间都有这样的一个实例,实例间彼此独立。所以同一台主机上的不同容器可以互不干扰地使用XFRM

  1. struct net
  2. {
  3. ......
  4. #ifdef CONFIG_XFRM
  5. struct netns_xfrm xfrm;
  6. #endif
  7. ......
  8. }

1.2 Netlink 通道

上面提到了Security Association和Security Policy信息,这些信息一般是由用户态IPsec进程(eg. StrongSwan)下发到内核XFRM的,这个下发的通道在network namespace初始化时创建。

  1. static int __net_init xfrm_user_net_init(struct net *net)
  2. {
  3. struct sock *nlsk;
  4. struct netlink_kernel_cfg cfg = {
  5. .groups = XFRMNLGRP_MAX,
  6. .input = xfrm_netlink_rcv,
  7. };
  8. nlsk = netlink_kernel_create(net, NETLINK_XFRM, &cfg);
  9. ......
  10. return 0;
  11. }

这样,当用户下发IPsec配置时,内核便可以调用 xfrm_netlink_rcv() 来接收

1.3 XFRM State

XFRM使用xfrm_state表示IPsec协议栈中的Security Association,它表示了一条单方向的IPsec流量所需的一切信息,包括模式(Transport或Tunnel)、密钥、replay参数等信息。用户态IPsec进程通过发送一个XFRM_MSG_NEWSA请求,可以让XFRM创建一个xfrm_state结构

xfrm_state包含的字段很多,这里就不贴了,仅仅列出其中最重要的字段:

  • id: 它是一个xfrm_id结构,包含该SA的目的地址、SPI、和协议(AH/ESP)
  • props:表示该SA的其他属性,包括IPsec Mode(Transport/Tunnel)、源地址等信息

每个xfrm_state在内核中会加入多个哈希表,因此,内核可以从多个特征查找到同一个个SA:

  • xfrm_state_lookup(): 通过指定的SPI信息查找SA
  • xfrm_state_lookup_byaddr(): 通过源地址查找SA
  • xfrm_state_find(): 通过目的地址查找SA

用户可以通过ip xfrm state ls命令列出当前主机上的xfrm_state

  1. src 192.168.0.1 dst 192.168.0.2
  2. proto esp spi 0xc420a5ed(3290473965) reqid 1(0x00000001) mode tunnel
  3. replay-window 0 seq 0x00000000 flag af-unspec (0x00100000)
  4. auth-trunc hmac(sha256) 0xa65e95de83369bd9f3be3afafc5c363ea5e5e3e12c3017837a7b9dd40fe1901f (256 bits) 128
  5. enc cbc(aes) 0x61cd9e16bb8c1d9757852ce1ff46791f (128 bits)
  6. anti-replay context: seq 0x0, oseq 0x1, bitmap 0x00000000
  7. lifetime config:
  8. limit: soft (INF)(bytes), hard (INF)(bytes)
  9. limit: soft (INF)(packets), hard (INF)(packets)
  10. expire add: soft 1004(sec), hard 1200(sec)
  11. expire use: soft 0(sec), hard 0(sec)
  12. lifetime current:
  13. 84(bytes), 1(packets)
  14. add 2019-09-02 10:25:39 use 2019-09-02 10:25:39
  15. stats:
  16. replay-window 0 replay 0 failed 0

1.3 XFRM Policy

XFRM使用xfrm_policy表示IPsec协议栈中的Security Policy,用户通过下发这样的规则,可以让XFRM允许或者禁止某些特征的流的发送和接收。用户态IPsec进程通过发送一个XFRM_MSG_POLICY请求,可以让XFRM创建一个 xfrm_policy 结构

  1. struct xfrm_policy {
  2. ......
  3. struct hlist_node bydst;
  4. struct hlist_node byidx;
  5. /* This lock only affects elements except for entry. */
  6. rwlock_t lock;
  7. atomic_t refcnt;
  8. struct timer_list timer;
  9. struct flow_cache_object flo;
  10. atomic_t genid;
  11. u32 priority;
  12. u32 index;
  13. struct xfrm_mark mark;
  14. struct xfrm_selector selector;
  15. struct xfrm_lifetime_cfg lft;
  16. struct xfrm_lifetime_cur curlft;
  17. struct xfrm_policy_walk_entry walk;
  18. struct xfrm_policy_queue polq;
  19. u8 type;
  20. u8 action;
  21. u8 flags;
  22. u8 xfrm_nr;
  23. u16 family;
  24. struct xfrm_sec_ctx *security;
  25. struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
  26. struct rcu_head rcu;
  27. };

这个结构的字段很多,但大部分并不用关心,我们重点关注下面列举出的这几个字段就行:

  • selector:表示该Policy匹配的流的特征
  • action:取值为XFRM_POLICY_ALLOW(0)或XFRM_POLICY_BLOCK(1),前者表示允许该流量,后者表示不允许。
  • xfrm_nr: 表示与这条Policy关联的template的数量,template可以理解为xfrm_state的简化版本,xfrm_nr决定了流量进行转换的次数,通常这个值为1
  • xfrm_vec: 表示与这条Policy关联的template,数组的每个元素是xfrm_tmpl, 一个xfrm_tmpl可以还原(resolve)成一个完成state

xfrm_state类似,用户可以通过ip xfrm policy ls命令列出当前主机上的xfrm_policy

  1. src 10.1.0.0/16 dst 10.2.0.0/16 uid 0
  2. dir out action allow index 5025 priority 383615 ptype main share any flag (0x00000000)
  3. lifetime config:
  4. limit: soft (INF)(bytes), hard (INF)(bytes)
  5. limit: soft (INF)(packets), hard (INF)(packets)
  6. expire add: soft 0(sec), hard 0(sec)
  7. expire use: soft 0(sec), hard 0(sec)
  8. lifetime current:
  9. 0(bytes), 0(packets)
  10. add 2019-09-02 10:25:39 use 2019-09-02 10:25:39
  11. tmpl src 192.168.0.1 dst 192.168.0.2
  12. proto esp spi 0xc420a5ed(3290473965) reqid 1(0x00000001) mode tunnel
  13. level required share any
  14. enc-mask ffffffff auth-mask ffffffff comp-mask ffffffff

2 接收发送IPsec报文

2.1 接收

下图展示了XFRM框架接收IPsec报文的流程:

 从整体上看,IPsec报文的接收是一个迂回的过程,IP层接收时,根据报文的protocol字段,如果它是IPsec类型(AH、ESP),则会进入XFRM框架进行接收,在此过程里,比较重要的过程是xfrm_state_lookup(), 该函数查找SA,如果找到之后,再根据不同的协议和模式进入不同的处理过程,最终,将原始报文的信息获取出来,重入ip_local_deliver().然后,还需经历XFRM Policy的过滤,最后再上送到应用层。

2.2 发送

下图展示了XFRM框架发送IPsec报文的流程:


XFRM在报文路由查找后查找是否有满足条件的SA,如果没有,则直接走ip_output(),否则进入XFRM的处理过程,根据模式和协议做相应处理,最后殊途同归到ip_output()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/814604
推荐阅读
相关标签
  

闽ICP备14008679号