Linux核心網路:實現和理論(2014)-第十章 IPsec
...
XFRM框架
IPsec基於XFRM(讀作“transform”)框架實現,該框架源於USAGI專案,其目標是提供一種產品化的IPv6和IPsec協議棧。術語“transform”指的是在核心協議棧中根據一些IPsec規則轉發入方向報文或者出方向報文。Linux核心2.5引入了XFRM框架,XFRM是一種協議族獨立的基本框架,這意味著對於IPv4和IPv6而言存在一個通用的部分,這部分位於net/xfrm之中。IPv4和IPv6擁有各自的ESP、AH和IPCOMP實現,例如IPv4
ESP模組位於net/ipv4/esp4.c,IPv6 ESP模組在net/ipv6/esp6.c中。除此之外,IPv4和IPv6為支援XFRM基本框架還實現了一些與各自協議相關的一些模組,比如net/ipv4/xfrm4_policy.c或者net/ipv6/xfrm6_policy.c。
XFRM框架支援網路名稱空間,這是一種輕量級的程式虛擬化,允許單個或者一組程式擁有自己的網路協議棧(在第14章會討論網路名稱空間)。每個網路名稱空間(資料型別struct net的例項)都包含一個名為xfrm的成員,該成員是資料型別struct netns_xfrm的例項。這個物件包含很多你在本章會碰到的資料結構和變數,比如XFRM策略雜湊表、XFRM狀態雜湊表、sysctl引數、XFRM狀態垃圾回收器、計數器等等。
struct netns_xfrm {
struct hlist_head *state_bydst;
struct hlist_head *state_bysrc;
struct hlist_head *state_byspi;
. . .
unsigned int state_num;
. . .
struct work_struct state_gc_work;
. . .
u32 sysctl_aevent_etime;
u32 sysctl_aevent_rseqth;
int sysctl_larval_drop;
u32 sysctl_acq_expires;
};
(include/net/netns/xfrm.h)
XFRM初始化
在IPv4中,XFRM初始化工作在xfrm_init()函式完成,其呼叫棧為ip_rt_init()->xfrm4_init()->xfrm_init(),ip_rt_init()方法位於net/ipv4/route.c檔案中。而在IPv6中,通過呼叫ipv6_route_init()方法中的xfrm6_init()方法實現了XFRM的初始化。通過建立NETLINK_XFRM型別netlink套接字(socket)併傳送/接收netlink訊息可以實現使用者空間和核心之間的通訊。
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;
}
從使用者空間發出的訊息(比如XFRM_MSG_NEWPOLICY建立新的安全策略或者XFRM_MSG_NEWSA建立新的安全聯盟)會被xfrm_netlink_rcv()方法處理,該方法又會被xfrm_user_rcv_msg()方法呼叫(第二章曾討論過netlink套接字)。
XFRM策略和XFRM狀態是XFRM框架的基礎資料結構,接下來我將陸續介紹什麼是XFRM策略以及XFRM狀態。
XFRM策略
安全策略是一種規則,告訴IPsec一條特定流量是否應該處理或者旁路,xfrm_policy結構用來描述IPsec策略。一個安全策略包含一個選擇器(一個xfrm_selector物件)。當其選擇器匹配一條流時會提供一種策略。XFRM選擇器有一系列屬性組成:比如source和destination address、source和destination port、protocol等等,用這些屬性來識別一條流:struct xfrm_selector {
xfrm_address_t daddr;
xfrm_address_t saddr;
__be16 dport;
__be16 dport_mask;
__be16 sport;
__be16 sport_mask;
__u16 family;
__u8 prefixlen_d;
__u8 prefixlen_s;
__u8 proto;
int ifindex;
__kernel_uid32_t user;
};
(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結構表示: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];
};
(include/net/xfrm.h)
下面將重點介紹一些xfrm_policy結構中重要的成員:- refcnt:XFRM引用計數,在xfrm_policy_alloc()方法中初始化為1,在xfrm_pol_hold()方法中增加計數,在xfrm_pol_put()方法中減少計數。
- timer:Per-policy定時器,定時器的回撥函式在xfrm_policy_alloc()方法中的xfrm_policy_timer()裡設定。xfrm_policy_timer()方法在策略到期時進行相關處理:某個策略到期後呼叫xfrm_policy_delete()方法時負責刪除對應策略,向通過呼叫km_policy_expired()方法註冊的Key Manager傳送XFRM_MSG_POLEXPIRE事件。
- lft:XFRM策略有效期(xfrm_lifetime_cfg物件),每一個XFRM策略都有一個有效期(使用時間或者位元組計數表示)。使用者可以使用ip命令和限制的引數設定XFRM有效期,比如:ip xfrm policy add src 172.16.2.0/24 dst 172.16.1.0/24 limit byte-soft 6000...該命令設定XFRM策略有效期的軟位元組限制是6000,請參閱幫助8-ip xfrm。您可以執行ip -stat xfrm policy show命令檢視有效期的配置項,顯示XFRM策略的有效期(lft)。
- curlft:XFRM策略當前的有效期,反映某個策略當前有效期的情況,curlft是一個xfrm_lifetime_cur物件,由四個成員組成,每個成員都是unsigned型別的64bit屬性
- bytes:IPsec子系統處理的位元組數量,在Tx路徑的xfrm_output_one()方法和Rx路徑的xfrm_input()方法中增加。
- packets:IPsec子系統處理的報文數量,在Tx路徑的xfrm_output_one()方法和Rx路徑的xfrm_input()方法中增加。
- add_time:新增策略的時間戳,在xfrm_policy_insert()方法和xfrm_sk_policy_insert()方法中新增策略時初始化。
- use_time:最新一次訪問策略的時間,在xfrm_lookup()方法或者_xfrm_policy_check()方法中更新use_time的時間戳,使用xfrm_policy_insert()方法和xfrm_sk_policy_insert()方法中新增策略時初始化為0。
- 注意:您可以執行ip -stat xfrm policy show命令檢視有效期的配置項,顯示某個XFRM策略的當前有效期(curlft)。
(未完待續)
原文源自網路,若有興趣可直接閱讀原文(http://apprize.info/linux/kernel/11.html)
相關文章
- 利用IPsec實現網路安全之五(Kerveros實現身份驗證)ROS
- Linux核心實現中斷和中斷處理(一)Linux
- 神經網路理論基礎及 Python 實現神經網路Python
- 利用IPsec實現網路安全之四(CA證書實現身份驗證)
- 《Linux核心設計與實現》——中斷和中斷處理Linux
- 網際網路協議安全IPSec協議
- 網路安全協議之IPsec協議
- ipsec-vpen核心demo
- 使用IPSec策略和規則提升網路安全性(二)
- 網際網路理財的現在和未來
- 深入討論通用許可權元件的理論和設計實現。元件
- 神經網路理論與工程實戰-知識積累神經網路
- 【Linux核心設計與實現】Linux核心簡介Linux
- 深入Linux網路核心堆疊(轉)Linux
- linux核心設計與實現Linux
- Linux下實現網際網路“過濾功能”(轉)Linux
- IPsec_VPN實現技術【轉載】
- Linux核心防火牆,工作在網路層Linux防火牆
- linux核心--使用核心佇列實現ringbufferLinux佇列
- BRDF理論及shader實現(下)
- 全面掌握膠囊網路:從基礎理論到PyTorch實戰PyTorch
- Linux 核心中斷和中斷處理(1)Linux
- 軟體測試理論和實踐
- Linux程式排程核心實現分析Linux
- 對偶理論和對偶單純形法——Python實現Python
- 基於Linux和IPSec的VPN閘道器Linux
- mongodb網路傳輸處理原始碼實現及效能調優-體驗核心效能極致設計MongoDB原始碼
- 《Linux核心設計與實現》學習【5】—— 核心同步Linux
- 1.Linux網路棧下兩層實現Linux
- Linux 的常用網路命令 實現資源共享Linux
- centos7實現上網和管理網路yum源CentOS
- 理論+實驗:Linux的DHCP原理與配置Linux
- 支援向量機(SVM)的約束和無約束優化、理論和實現優化
- 2014年中國網際網路金融理財報告——資訊圖
- Linux對ipsec的支援Linux
- Kubernetes 容器網路模型和典型實現模型
- 使用JavaScript實現機器學習和神經學網路JavaScript機器學習
- Retrofit和OkHttp實現 Android網路快取HTTPAndroid快取