分享
 
 
 

PF_KEY接口在OpenBSD内核中的实现

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

PF_KEY协议是IPSec的重要组成部分。密钥管理进程利用PF_KEY与内核的SADB进行通信,实现SA(Security Association,安全联盟)和SP(Security Policy,安全策略)的管理。本文将从PF_KEY协议构造和PF_KEY相关系统调用等方面描述OpenBSD内核中的PF_KEY实现。

利用IPSec技术可在IP层实现对数据包进行保护,降低了互联网通信的风险。IPsec的安全服务是由通信双方建立的安全联盟(SA)来提供的。IPsec系统在处理输入/输出IP 流时必须参考安全策略库(SPD),并根据从SPD中提取的策略对IP流进行不同的处理,例如拒绝、绕过和进行IPsec保护。SA和SPD的管理是利用PF_key API来实现用户进程和内核之间的通信,可以通过手工进行,也可以通过IKE来进行动态协商。

PF_KEY是用户进程操作内核中的SADB(Security Associations Database)和SPD的编程接口。下面将从协议族构造、系统调用和PF_KEY socket实现三部分加以描述。

协议族构造

Net/3组把协议关联到一个域中,并且用一个协议族常量来标识每个域。在OpenBSD定义的域包含以下的四个,分别是路由协议族、IP协议族、Unix协议族和PF_KEY协议族。同时定义了全局指针型变量domains,由它将协议族结构链接在一起。

初始化完成后,内核构建了图1所示的数据结构。pfkey_domain定义的协议族为PF_KEY,Socket地址为PF_KEY。

在PF_KEY协议初始化过程中,系统还定义了指针数组,用于指向含有Socket操作函数的不同版本pfkey_version结构。pfkey_version结构定义在sys/net/pfkeyv2.h文件中。

图1 初始化后的domain链表和protosw数组

目前OpenBSD实现的PF_KEY版本是2.0,该指针数组结构定义如下:

struct pfkey_version

{

int protocol;

int (*create)(struct socket socket);

int (*release)(struct socket *socket);

int (*send)(struct socket *socket, void *message, int len);

} = { PFKEYV2_PROTOCOL,

&pfkeyv2_create, &pfkeyv2_release, &pfkeyv2_send };

PF_KEY socket实现

PF_KEY socket系统调用

当一个应用调用Socket时,进程用系统调用机制将三个独立的整数传给内核。syscall将参数复制到32bit值的数组中,并将数组指针作为第二个参数传给Socket的内核版。内核版的Socket将第二个参数“uap”作为指向sys_socket_args结构的指针。图2显示了上述过程。

图2 用户空间Socket参数到内核空间转换图

当进程调用socket(PF_KEY,SOCK_RAW, PF_KEY_V2)时,内核sys_socket()向PF_KEY协议中pfkey_protosw(见图1)定义的pfkey_usrreq()发送PRU_ATTACH,调用如下:

error=(*prp-pr_usrreq)(so,PRU_ATTACH,NULL,(struct mbuf *)(long)proto,NULL);

Pfkey_usrreq()处理PRU_ATTACH请求,创建协议控制块。

PF_KEY close()系统调用

内核中sys_close()对应用户空间的close()系统调用,用来关闭各类描述符。当fd是引用对象的最后描述符时,与对象有关的close函数被调用如下:

error=(*fp-f_ops-fo_close)(fp, p);

Socket的fp-f_ops-fo_close是soo_close()函数。soo_close()是soclose()函数的封装器。soclose()取消Socket上相关连接并释放不需要的数据结构,发送PRU_DETACH请求断开Socket与PF_KEY协议的联系,最后调用sofree()释放PF_KEY socket。

error2=(*so-so_proto-pr_usrreq)(so, PRU_DETACH, NULL,NULL, NULL);

Pfkey_usrreq()响应soclose()的PRU_DETACH请求,释放该Socket协议控制块,并将该Socket从pfkeyv2_sockets链表中删除。

PF_KEY 读写系统调用

所有的写系统调用都要直接或间接地调用sosend。sosend的功能是将进程来的数据复制到内核,并将数据传递给与插口相关的协议,如下:

error=(*so-so_proto-pr_usrreq)(so, PRU_SEND, top, addr, control);

对于PF_KEY的Socket,pfkey_usrreq()间接调用pfkey_output(),pfkey_output()直接调用pfkeyv2_send()。

所有处理用户消息的工作全部在pfkeyv2_send()内完成,包括SA的增加、删除、清空和请求操作等。pfkeyv2_send()通过pfkeyv2_sendup()将结果放入Socket的接收缓冲区中,并通知用户进程接收缓存已改变。

同写调用一样,用户空间的读调用如read和recv等,都是由内核中的一个公共函数soreceive()来完成所有的工作。sorecevice()函数将数据从Socket的接口缓存传送到进程指定的缓存中。

sorecevice是一个复杂的函数,导致其复杂的主要原因是繁琐的指针操作及对多种类型的数据(带外数据、地址、控制信息和正常数据)和多目标(进程缓存和mbuf链)的处理。

最后在这里列出PF_KEY的接口实现的相关系统调用图,见图3。

图3 PF_KEY内核调用图

结束语

本文主要描述了PF_KEY接口在OpenBSD内核中的实现。通过该接口,可以实现IPSec的SA和SP的自动和手工配置管理。作为IPSec的重要组成部分,SADB和SPD与PF_KEY有着紧密的联系,但本文中没有具体描述。想要深入了解的IPSec的整体实现,阅读源码是比较有效的方法之一。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有