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

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

Overview

XFRM 实例

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

struct net

{

......

#ifdef CONFIG_XFRM

struct netns_xfrm xfrm;

#endif

......

}

Netlink 通道

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

static int __net_init xfrm_user_net_init(struct net *net)

{

struct sock *nlsk;

struct netlink_kernel_cfg cfg = {

.groups = XFRMNLGRP_MAX,

.input = xfrm_netlink_rcv,

};

nlsk = netlink_kernel_create(net, NETLINK_XFRM, &cfg);

......

return 0;

}

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

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

src 192.168.0.1 dst 192.168.0.2

proto esp spi 0xc420a5ed(3290473965) reqid 1(0x00000001) mode tunnel

replay-window 0 seq 0x00000000 flag af-unspec (0x00100000)

auth-trunc hmac(sha256) 0xa65e95de83369bd9f3be3afafc5c363ea5e5e3e12c3017837a7b9dd40fe1901f (256 bits) 128

enc cbc(aes) 0x61cd9e16bb8c1d9757852ce1ff46791f (128 bits)

anti-replay context: seq 0x0, oseq 0x1, bitmap 0x00000000

lifetime config:

limit: soft (INF)(bytes), hard (INF)(bytes)

limit: soft (INF)(packets), hard (INF)(packets)

expire add: soft 1004(sec), hard 1200(sec)

expire use: soft 0(sec), hard 0(sec)

lifetime current:

84(bytes), 1(packets)

add 2019-09-02 10:25:39 use 2019-09-02 10:25:39

stats:

replay-window 0 replay 0 failed 0

XFRM Policy

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

struct xfrm_policy {

......

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];

struct rcu_head rcu;

};

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

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

src 10.1.0.0/16 dst 10.2.0.0/16 uid 0

dir out action allow index 5025 priority 383615 ptype main share any flag (0x00000000)

lifetime config:

limit: soft (INF)(bytes), hard (INF)(bytes)

limit: soft (INF)(packets), hard (INF)(packets)

expire add: soft 0(sec), hard 0(sec)

expire use: soft 0(sec), hard 0(sec)

lifetime current:

0(bytes), 0(packets)

add 2019-09-02 10:25:39 use 2019-09-02 10:25:39

tmpl src 192.168.0.1 dst 192.168.0.2

proto esp spi 0xc420a5ed(3290473965) reqid 1(0x00000001) mode tunnel

level required share any

enc-mask ffffffff auth-mask ffffffff comp-mask ffffffff

接收发送IPsec报文

接收

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

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

发送

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

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

REF

Linux Kernel Networing Implementation and Throry

linux ipsec内核,XFRM -- IPsec协议的内核实现框架相关推荐

  1. IPsec:XFRM -- IPsec协议的内核实现框架

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

  2. linux内核协议栈 邻居协议之 arp 数据包收发处理流程

    目录 前言 1 arp数据包文接收 arp_rcv() 1.1 处理arp请求 arp_process()[核心] 2 arp数据包发送 arp_send() 2.1 arp 数据包构造 arp_cr ...

  3. 戴文的linux内核专题 24,戴文的Linux内核专题:26 配置内核 (22)

    你好!本篇我们将继续配置quot;kernel hacksquot;,接着我们会配置整个安全系统. Alpha和s390处理器需要配置下一个特性(Force weak per-cpu definiti ...

  4. Linux内核中网络数据包的接收框架

    与网络数据包的发送不同,网络收包是异步的的,因为你不确定谁会在什么时候突然发一个网络包给你,因此这个网络收包逻辑其实包含两件事: 1.数据包到来后的通知 2.收到通知并从数据包中获取数据 这两件事发生 ...

  5. linux基础—课堂随笔010_系统启动和内核管理

    系统启动和内核管理 Linux: kernel+rootfs kernel: 进程管理.内存管理.网络管理.驱动程序.文件系统.安全功能 rootfs:程序和glibc 库:函数集合, functio ...

  6. 《嵌入式Linux与物联网软件开发——C语言内核深度解析》一第1章 C语言与内存1.1 引言...

    本节书摘来自异步社区<嵌入式Linux与物联网软件开发--C语言内核深度解析>一书中的第1章,第1.1节,作者朱有鹏 , 张先凤,更多章节内容可以访问云栖社区"华章计算机&quo ...

  7. linux c内核开发,嵌入式uClinux的内核结构和开发环境

    1 引言 嵌入式操作系统是嵌入式系统的灵魂,而且在同一个硬件平台上可以嵌入不同的嵌入式操作系统.比如ARM7TDMI内核,可以嵌入Nucleus.VxWorks.uClinux等操作系统.在此主要对u ...

  8. 【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )

    文章目录 一.禁止 / 开启内核抢占 与 方法保护临界区 二.编译器优化屏障 三.preempt_disable 禁止内核抢占 源码 四.preempt_enable 开启内核抢占 源码 一.禁止 / ...

  9. 【Linux 内核】Linux 内核体系架构 ( 硬件层面 | 内核空间 | 用户空间 | 内核态与用户态切换 | 系统调用 | 体系结构抽象层 )

    文章目录 一.Linux 内核体系架构 二.内核态与用户态切换 ( 系统调用层 ) 三.体系结构抽象层 一.Linux 内核体系架构 Linux 内核最初的源码不足一万行 , 当前的 Linux 内核 ...

最新文章

  1. Python笔记(2)函数
  2. Microbiome:掠食性粘细菌通过调节土壤微生物群落来控制黄瓜枯萎病
  3. Ehab Is an Odd Person
  4. CS231n Convolutional Neural Networks for Visual Recognition------Scipy and MatplotlibTutorial
  5. 一、PHP框架Laravel——入门和安装
  6. mysql 数据库中数据去重,oracle数据库中如何达到像mysql数据库中group by 那种去重的效果..求大神解答...
  7. ISSN和EAN原理及转换【转载】
  8. 虚拟服务器声卡,如何使用虚拟声卡?虚拟声卡安装教程!
  9. 一步步学习NHibernate(8)——HQL查询(2)
  10. Linux基本命令总结(六)
  11. ionic3.0--angular4.0 引入第三方插件库的方法
  12. android获取签名信息
  13. 计算机基础(四):C语言字符串处理文件保存
  14. 搜索框键盘抬起事件2
  15. 路由器(Tenda 811R)变砖——修复
  16. 群晖 android软件,群晖-手机端常用App
  17. 基因重组-冲刺日志(第九天)
  18. 满秩矩阵可以初等变换成单位矩阵吗?
  19. 简单学JAVA-Java学习方法-费曼学习法
  20. android studio增加一个界面,Android Studio在同一个窗口中打开多个Project【附效果图附源码...

热门文章

  1. J9数字论:数字圈的FOMO现象该如何杜绝?
  2. 排他平方数(使用C语言基础)
  3. 【面试题】大数据方向
  4. **6-7 十进制转换二进制 (10分)**
  5. RF框架----基础
  6. 常用win7 快捷键
  7. Loadrunner C/S关联函数(LSP)AND(LSSS)使用-案例
  8. ipscan端口扫描工具
  9. 计算机硬件设备ppt教案,计算机的硬件组成课件.ppt
  10. java中使用pdfBox打印pdf;java web打印pdf;静默打印;jar程序打包成exe文件;exe4j的使用