XFRM--A Kernel Implementation Framework of IPsec Protocol

Posted by Blu_Smurf on Tue, 17 Sep 2019 15:04:18 +0200

IPsecAgreement help IP Layer establishes secure and trusted data transmission channel. At present, there are such things as StrongSwan,OpenSwan And other mature solutions, and they all use Linux KernelXFRMThe framework receives and sends messages.


XFRMThe correct pronunciation istransform(Transformation), This represents what the kernel protocol stack receivesIPsecMessages need to go throughTransformationIn order to restore to the original message; similarly, the original message to be sent also needs to be converted to IPsec Messages can only be sent out.

Overview

XFRM Example

IPsec There are two important concepts: Security Association(Security Association)Security strategy(Security Policy),Both types of information need to be stored in the kernelXFRM. nucleusXFRMUsenetns_xfrmThis structure organizes this information, which is also known as xfrm instance(Example). As can be seen from its name, this example is network namespace Relevantly, each namespace has an instance that is independent of each other. So different containers on the same host can be used without interference.XFRM

struct net
{
    ......
   #ifdef CONFIG_XFRM
    struct netns_xfrm    xfrm;
    #endif 
    ......
}

Netlink channel

Security Association and Security Policy information are mentioned above, which are typically sent to the kernel XFRM by the user-mode IPsec process (eg. StrongSwan), which is created when the network namespace is initialized.

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;
}

In this way, when the user downloads the IPsec configuration, the kernel can call xfrm_netlink_rcv() to receive it.

XFRM State

XFRM uses xfrm_state to represent the Security Association in the IPsec stack. It represents all the information needed for a unidirectional IPsec traffic, including the information of the mode (Transport or Tunnel), the key, the replacement parameter, and so on. User-mode IPsec process allows XFRM to create an xfrm_state structure by sending an XFRM_MSG_NEWSA request

xfrm_state contains many fields, which are not posted here, but only the most important fields are listed:

  • Id: It is an xfrm_id structure that contains the SA's destination address, SPI, and protocol (AH/ESP)
  • props: Represents other attributes of the SA, including information such as IPsec Mode(Transport/Tunnel), source address, etc.

Each xfrm_state adds multiple hash tables to the kernel, so the kernel can find the same SA from multiple features:

  • xfrm_state_lookup(): Find SA by specifying SPI information
  • xfrm_state_lookup_byaddr(): Find SA by source address
  • xfrm_state_find(): Find SA by destination address

Users can list xfrm_state on the current host through the IP xfrm state command

src 192.168.0.1 dst 192.168.0.2
    proto esp spi 0xc420a5ed(3290473965) reqid 1(0x00000001) mode tunnel
    replay-window 0 seq 0x00000000 flag af-unspec (0x00100000)
    auth-trunc hmac(sha256) 0xa65e95de83369bd9f3be3afafc5c363ea5e5e3e12c3017837a7b9dd40fe1901f (256 bits) 128
    enc cbc(aes) 0x61cd9e16bb8c1d9757852ce1ff46791f (128 bits)
    anti-replay context: seq 0x0, oseq 0x1, bitmap 0x00000000
    lifetime config:
      limit: soft (INF)(bytes), hard (INF)(bytes)
      limit: soft (INF)(packets), hard (INF)(packets)
      expire add: soft 1004(sec), hard 1200(sec)
      expire use: soft 0(sec), hard 0(sec)
    lifetime current:
      84(bytes), 1(packets)
      add 2019-09-02 10:25:39 use 2019-09-02 10:25:39
    stats:
      replay-window 0 replay 0 failed 0

XFRM Policy

XFRMUsexfrm_policyExpress IPsec In the protocol stack Security Policy,By issuing such rules, users can makeXFRMAllow or prohibit the sending and receiving of streams with certain characteristics. User state IPsec A process sends a XFRM_MSG_POLICY Request, can letXFRMCreate axfrm_statestructure

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];
    struct rcu_head        rcu;
};

There are many fields in this structure, but most of them don't need to be concerned. We should focus on these fields listed below.

  • selector: Represents the characteristics of the flow that the Policy matches
  • action: Take the value XFRM_POLICY_ALLOW(0) or XFRM_POLICY_BLOCK(1), the former means to allow the traffic, the latter means not.
  • Xfrm_nr: Represents the number of templates associated with this Policy. The template can be understood as a simplified version of xfrm_state. xfrm_nr determines the number of times traffic is converted. Usually this value is 1.
  • xfrm_vec: Represents the template associated with this Policy. Each element of the array is xfrm_tmpl. An xfrm_tmpl can be resolved into a completed state.

Similar to xfrm_state, users can list xfrm_policy on the current host through the IP xfrm policies command

src 10.1.0.0/16 dst 10.2.0.0/16 uid 0
    dir out action allow index 5025 priority 383615 ptype main share any flag  (0x00000000)
    lifetime config:
      limit: soft (INF)(bytes), hard (INF)(bytes)
      limit: soft (INF)(packets), hard (INF)(packets)
      expire add: soft 0(sec), hard 0(sec)
      expire use: soft 0(sec), hard 0(sec)
    lifetime current:
      0(bytes), 0(packets)
      add 2019-09-02 10:25:39 use 2019-09-02 10:25:39
    tmpl src 192.168.0.1 dst 192.168.0.2
        proto esp spi 0xc420a5ed(3290473965) reqid 1(0x00000001) mode tunnel
        level required share any 
        enc-mask ffffffff auth-mask ffffffff comp-mask ffffffff

Receiving and sending IPsec messages

Receive

The following figure shows the process of receiving IPsec messages by the XFRM framework:

On the whole, IPsec message reception is a circuitous process. When IP layer receives a message, according to the protocol field of the message, if it is IPsec type (AH, ESP), it will enter the XFRM framework to receive it. In this process, the more important process is xfrm_state_lookup(), which looks for SA, and if it is found, it will be rooted again. According to different protocols and modes, it enters into different processing processes. Finally, the information of the original message is retrieved and re-entered into ip_local_delivery(). Then, it needs to undergo XFRM Policy filtering and finally uploaded to the application layer.

Send out

The following figure shows the process of sending IPsec messages by the XFRM framework:

XFRM finds out whether SA meets the requirement after message routing lookup. If not, it goes directly to ip_output(), otherwise it goes into the process of XFRM, and does the corresponding processing according to the mode and protocol. Finally, it returns to ip_output() by different routes.

REF

  • Linux Kernel Networing Implementation and Throry

Topics: Linux network