一篇走進(jìn)Linux內(nèi)核之XFRM框架
在此前的文章中討論了Linux內(nèi)核中Netfilter子系統(tǒng)的基本架構(gòu)及其實(shí)現(xiàn)原理,本篇文章將討論Linux內(nèi)核另一個(gè)重要的子系統(tǒng)——XFRM框架。
下面開(kāi)始上才藝,帶你走進(jìn)Linux內(nèi)核之XFRM框架。
概述:什么是XFRM框架
XFRM的正確讀音是transform(轉(zhuǎn)換), 這表示內(nèi)核協(xié)議棧收到的IPsec報(bào)文需要經(jīng)過(guò)轉(zhuǎn)換才能還原為原始報(bào)文;
同樣地,要發(fā)送的原始報(bào)文也需要轉(zhuǎn)換為IPsec報(bào)文才能發(fā)送出去。
IPsec(Internet協(xié)議安全)應(yīng)該很多人都聽(tīng)過(guò),IPsec是一組協(xié)議,他們通過(guò)對(duì)通信會(huì)話中的每個(gè)數(shù)據(jù)包進(jìn)行身份驗(yàn)證和加密,以確保IP流量的安全。
XFRM框架是IPsec的“基礎(chǔ)設(shè)施”,IPsec通過(guò)XFRM框架實(shí)現(xiàn)的。XFRM源自USAGI項(xiàng)目,該項(xiàng)目旨在提供適用于生產(chǎn)環(huán)境的IPv6和IPsec協(xié)議棧。自內(nèi)核2.5之后引入了XFRM框架,這個(gè)“基礎(chǔ)設(shè)施”獨(dú)立于協(xié)議簇,包含可同時(shí)應(yīng)用于IPv4和IPv6的通用部分,位于源代碼的net/xfrm/目錄下。
XFRM框架支持網(wǎng)絡(luò)命名空間。這是一種輕型的進(jìn)程虛擬化,它可以使得一個(gè)或者一組進(jìn)程有屬于自己的網(wǎng)絡(luò)棧。每個(gè)網(wǎng)絡(luò)命名空間都含有一個(gè)名為xfrm的成員——一個(gè)netns_xfrm結(jié)構(gòu)實(shí)例。這個(gè)對(duì)象包含著許多的數(shù)據(jù)結(jié)構(gòu)和變量,例如:XFRM策略散列表、XFRM狀態(tài)散列表、sysctl參數(shù)、XFRM狀態(tài)垃圾收集器、計(jì)數(shù)器等。
netns_xfrm結(jié)構(gòu)體定義,文件路徑include/net/netns/xfrm.h
XFRM初始:XFRM Init
在IPv4中,XFRM初始化是通過(guò)在ip_rt_init()函數(shù)(位于net/ipv4/route.c文件)調(diào)用相關(guān)函數(shù)完成,函數(shù)調(diào)用結(jié)構(gòu)為:ip_rt_init()->xfrm4_init()->xfrm_init()。
而在IPv6中,在ipv6_route_init()函數(shù)中調(diào)用xfrm6_init()方法實(shí)現(xiàn)了XFRM的初始化。
用戶空間和內(nèi)核之間的通信創(chuàng)建NETLINK_XFRM類(lèi)型netlink套接字(socket)以及發(fā)送和接收netlink消息來(lái)完成。內(nèi)核NETLINK_XFRM Netlink套接字是在下面的函數(shù)中完成創(chuàng)建。
從用戶空間發(fā)出的消息(比如XFRM_MSG_NEWPOLICY創(chuàng)建新的安全策略或者XFRM_MSG_NEWSA創(chuàng)建新的安全聯(lián)盟)會(huì)被xfrm_netlink_rcv()方法處理,該方法又會(huì)被xfrm_user_rcv_msg()方法調(diào)用(第二章曾討論過(guò)netlink套接字)。
XFRM策略和XFRM狀態(tài)是XFRM框架的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),接下來(lái)我將陸續(xù)介紹什么是XFRM策略 以及XFRM狀態(tài) 。
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)? ?


XFRM策略:XFRM Policy
安全策略是一種規(guī)則,告訴IPsec一條特定流量是否應(yīng)該處理或者旁路,xfrm_policy結(jié)構(gòu)用來(lái)描述IPsec策略。一個(gè)安全策略包含一個(gè)選擇器(一個(gè)xfrm_selector對(duì)象)。當(dāng)其選擇器匹配一條流時(shí)會(huì)提供一種策略。XFRM選擇器有一系列屬性組成:比如source和destination address、source和destination port、protocol等等,用這些屬性來(lái)識(shí)別一條流:
文件路徑:include/uapi/linux/xfrm.h
xfrm_selector_match()方法使用XFRM selector、flow和family(IPv4對(duì)應(yīng)AF_INET,IPv6對(duì)應(yīng)AF_INET6)作為參數(shù),當(dāng)特定XFRM流量匹配中特定選擇器時(shí)返回true。注意xfrm_selector結(jié)構(gòu)同樣用在XFRM狀態(tài)中。
安全策略(Security Policy)使用xfrm_policy結(jié)構(gòu)表示,xfrm_policy結(jié)構(gòu)用于描述SP在內(nèi)核內(nèi)部的具體實(shí)現(xiàn):
文件路徑:include/net/xfrm.h
這個(gè)結(jié)構(gòu)的字段很多,但大部分并不用關(guān)心,我們重點(diǎn)關(guān)注下面列舉出的這幾個(gè)字段就行:
selector:表示該P(yáng)olicy匹配的流的特征
action:取值為XFRM_POLICY_ALLOW(0)或XFRM_POLICY_BLOCK(1),前者表示允許該流量,后者表示不允許。
xfrm_nr: 表示與這條Policy關(guān)聯(lián)的template的數(shù)量,template可以理解為xfrm_state的簡(jiǎn)化版本,xfrm_nr決定了流量進(jìn)行轉(zhuǎn)換的次數(shù),通常這個(gè)值為1
xfrm_vec: 表示與這條Policy關(guān)聯(lián)的template,數(shù)組的每個(gè)元素是xfrm_tmpl, 一個(gè)xfrm_tmpl可以還原(resolve)成一個(gè)完成state.
用戶可以通過(guò)下面命令,列出當(dāng)前主機(jī)上的xfrm_policy
XFRM狀態(tài):XFRM State
結(jié)構(gòu)xfrm_state表示IPsec安全關(guān)聯(lián)(include/net/xfrm.h)。它表示的是單向流量,包含加密密鑰、標(biāo)志、請(qǐng)求ID、統(tǒng)計(jì)信息、重放參數(shù)等信息。要添加X(jué)FRM狀態(tài),可從用戶空間套接字發(fā)送請(qǐng)求XFRM_MSG_NEWSA,在內(nèi)核中,這種請(qǐng)求方法由xfrm_state_add()處理(位于文件net/xfrm/xfrm_user.c)。同樣,要?jiǎng)h除狀態(tài),可發(fā)送XFRM_MSG_NEWSAXFRM_MSG_DELSA消息,在內(nèi)核中,這種請(qǐng)求方法由xfrm_del_sa()處理。 xfrm_state狀態(tài)結(jié)構(gòu)用來(lái)描述SA在內(nèi)核中的具體實(shí)現(xiàn):
xfrm_state包含的字段很多,這里就不貼了,僅僅列出其中最重要的字段:
id: 它是一個(gè)xfrm_id結(jié)構(gòu),包含該SA的目的地址、SPI、和協(xié)議(AH/ESP)
props:表示該SA的其他屬性,包括IPsec Mode(Transport/Tunnel)、源地址等信息
每個(gè)xfrm_state在內(nèi)核中會(huì)加入多個(gè)哈希表,因此,內(nèi)核可以從多個(gè)特征查找到同一個(gè)個(gè)SA:
xfrm_state_lookup(): 通過(guò)指定的SPI信息查找SA
xfrm_state_lookup_byaddr(): 通過(guò)源地址查找SA
xfrm_state_find(): 通過(guò)目的地址查找SA
用戶可以通過(guò)下面命令,列出當(dāng)前主機(jī)上的xfrm_state
XFRM模板:XFRM TMPL
xfrm模板結(jié)構(gòu), 用于狀態(tài)和策略的查詢:
