欢迎光临散文网 会员登陆 & 注册

一篇走进Linux内核之XFRM框架

2022-09-23 20:19 作者:补给站Linux内核  | 我要投稿

在此前的文章中讨论了Linux内核中Netfilter子系统的基本架构及其实现原理,本篇文章将讨论Linux内核另一个重要的子系统——XFRM框架。

下面开始上才艺,带你走进Linux内核之XFRM框架。

概述:什么是XFRM框架

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

同样地,要发送的原始报文也需要转换为IPsec报文才能发送出去。

IPsec(Internet协议安全)应该很多人都听过,IPsec是一组协议,他们通过对通信会话中的每个数据包进行身份验证和加密,以确保IP流量的安全。

XFRM框架是IPsec的“基础设施”,IPsec通过XFRM框架实现的。XFRM源自USAGI项目,该项目旨在提供适用于生产环境的IPv6和IPsec协议栈。自内核2.5之后引入了XFRM框架,这个“基础设施”独立于协议簇,包含可同时应用于IPv4和IPv6的通用部分,位于源代码的net/xfrm/目录下。

XFRM框架支持网络命名空间。这是一种轻型的进程虚拟化,它可以使得一个或者一组进程有属于自己的网络栈。每个网络命名空间都含有一个名为xfrm的成员——一个netns_xfrm结构实例。这个对象包含着许多的数据结构和变量,例如:XFRM策略散列表、XFRM状态散列表、sysctl参数、XFRM状态垃圾收集器、计数器等。

netns_xfrm结构体定义,文件路径include/net/netns/xfrm.h

XFRM初始:XFRM Init

在IPv4中,XFRM初始化是通过在ip_rt_init()函数(位于net/ipv4/route.c文件)调用相关函数完成,函数调用结构为:ip_rt_init()->xfrm4_init()->xfrm_init()。

而在IPv6中,在ipv6_route_init()函数中调用xfrm6_init()方法实现了XFRM的初始化。

用户空间和内核之间的通信创建NETLINK_XFRM类型netlink套接字(socket)以及发送和接收netlink消息来完成。内核NETLINK_XFRM Netlink套接字是在下面的函数中完成创建。

从用户空间发出的消息(比如XFRM_MSG_NEWPOLICY创建新的安全策略或者XFRM_MSG_NEWSA创建新的安全联盟)会被xfrm_netlink_rcv()方法处理,该方法又会被xfrm_user_rcv_msg()方法调用(第二章曾讨论过netlink套接字)。

XFRM策略和XFRM状态是XFRM框架的基础数据结构,接下来我将陆续介绍什么是XFRM策略 以及XFRM状态 。


【文章福利】小编推荐自己的Linux内核技术交流群:【891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)   

XFRM策略:XFRM Policy

安全策略是一种规则,告诉IPsec一条特定流量是否应该处理或者旁路,xfrm_policy结构用来描述IPsec策略。一个安全策略包含一个选择器(一个xfrm_selector对象)。当其选择器匹配一条流时会提供一种策略。XFRM选择器有一系列属性组成:比如source和destination address、source和destination port、protocol等等,用这些属性来识别一条流:

文件路径:include/uapi/linux/xfrm.h

xfrm_selector_match()方法使用XFRM selector、flow和family(IPv4对应AF_INET,IPv6对应AF_INET6)作为参数,当特定XFRM流量匹配中特定选择器时返回true。注意xfrm_selector结构同样用在XFRM状态中。

安全策略(Security Policy)使用xfrm_policy结构表示,xfrm_policy结构用于描述SP在内核内部的具体实现:

文件路径:include/net/xfrm.h

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

  • 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_policy

XFRM状态:XFRM State

结构xfrm_state表示IPsec安全关联(include/net/xfrm.h)。它表示的是单向流量,包含加密密钥、标志、请求ID、统计信息、重放参数等信息。要添加XFRM状态,可从用户空间套接字发送请求XFRM_MSG_NEWSA,在内核中,这种请求方法由xfrm_state_add()处理(位于文件net/xfrm/xfrm_user.c)。同样,要删除状态,可发送XFRM_MSG_NEWSAXFRM_MSG_DELSA消息,在内核中,这种请求方法由xfrm_del_sa()处理。 xfrm_state状态结构用来描述SA在内核中的具体实现:

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

用户可以通过下面命令,列出当前主机上的xfrm_state

XFRM模板:XFRM TMPL

xfrm模板结构, 用于状态和策略的查询:

一篇走进Linux内核之XFRM框架的评论 (共 条)

分享到微博请遵守国家法律