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)


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值