首页 > 编程知识 正文

linux ipsec内核XFRM IPsec协议的内核实现框架

时间:2023-05-05 01:00:58 阅读:157530 作者:2068

IPsec协议有助于IP层建立安全可靠的分组传输通道。 目前有比较成熟的解决方案,如StrongSwan、OpenSwan等,它们使用Linux内核中的XFRM框架来发送和接收消息。

正确读取XFRM是transform (转换),这意味着内核协议栈收到的IPsec消息必须进行转换才能还原为原始消息。 同样,要发送的原始消息也必须转换为IPsec消息才能发送。

Overview

XFRM实例

IPsec有两个重要概念:安全关联(Security Association )和安全策略(Security Policy ),这些信息必须存储在内核XFRM中。 核心XFRM使用名为netns_xfrm的结构来组织这些信息。 这也称为xfrm实例(实例)。 从名称中可以看出,此实例与network namespace相关,每个命名空间在实例之间都有独立的实例。 因此,在同一主机上的不同容器可以使用XFRM而不相互干扰

结构网络

{

……

#ifdef CONFIG_XFRM

struct netns_xfrm xfrm;

#endif

……

() ) ) ) )。

网络频道

上面提到了安全关联和安全策略的信息,这些信息一般通过用户状态的IPsec进程(eg. StrongSwan )分发到内核XFRM,然后进行该分发

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

……

返回0;

() ) ) ) )。

这可以允许内核在用户分发IPsec设置时,调用并接收xfrm_netlink_rcv ()

XFRM State

XFRM使用xfrm_state表示IPsec协议栈中的安全关联。 它表示单向IPsec通信所需的所有信息,包括模式(Transport或Tunnel )、密钥和replay参数。 用户状态IPsec进程可以通过发送XFRM_MSG_NEWSA请求在XFRM中创建xfrm_state结构

xfrm_state包含许多字段,但在此不粘贴。 只显示其中最重要的字段。

id:是xfrm_id结构体,其包括SA的目的地地址、SPI和协议(AH/ESP )

props :表示此SA的其他属性,例如IPSec mode (传输/隧道)、源地址等

每个xfrm_state向内核中添加多个散列表,以便内核可以从多个特征中找到同一个SA。

xfrm_state_lookup (:使用指定的SPI信息搜索SA

xfrm _ state _ lookup _ by addr (从:源地址中查找SA

xfrm_state_find(:将从目标地址中搜索SA

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

src 192.168.0.1 dst 192.168.0.2

protoespspi0x c 420 a5ed (3290473965 ) reqid1)0x0000001 )模式隧道

replay-window0seq0x 0000000 flag af-un spec (0x 00100000 ) )。

auth-trunchmac(sha256 )0x a 65e 95 de 83369 BD9F3 be3afafc 5c 363 e5e 12 c 3017837 a7B9 DD 40 Fe 1901 f ) 256bits ) 128

ENCCBC(AES )0x 61 CD 9e 16 bb 8c1 d 9757852 ce1ff 46791 f (128 bits ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )。

anti-replay context: seq0x0、oseq0x1、bitmap0x00000000

生命配置:

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

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

ts)

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

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。