strongswan SA分析(一)

1 概念

下面主要介绍两个本文将要阐述的核心概念。他们是SA和SP。注意,这不是一篇不需要背景知识的文章。作者认为你适合阅读接下来内容的的前提是,你已经具备了一下三方面的知识:

  • a. 什么是VPN。
  • b. 什么是IPsec,包括IKE,ESP,strongswan都是什么等。
  • c. 一般的linux使用方法和常见概念。

1.1 什么是SAD,SPD

SAD是Security Association Database的缩写。

SPD是Security Policy Database的缩写。

SAD是用来存储SA的数据库。SPD是用来存储SP的数据库。

1.2 什么是SPI

SPI是Security Parameter Index的缩写。是有一组数字(长度?)。被使用在SAD和SPD里作为索引的一部分。是由IKE协商的两侧客户端随机选择的UUID?。0-255是被保留的值,禁止在SPI中使用。

1.3 什么是SA

SA是Security Association的缩写。SA是一组算法和算法参数(包括key)的集合,用来完成单个方向的数据流加密和验证任务。通过SPI加数据包的目的地址可以唯一查找到一个SA。

包含的属性:

  • 加密算法

    • 属性
    • key
  • 验证算法
    • 属性
    • key
  • SPI
  • 目的地址

1.4 什么是SP

SP是Security Policy的缩写。SP是一条规则,决定一条流(flow)是否需要被IPsec处理。SP的处理有三种方式:

  • 丢弃
  • 不处理
  • 处理

需要被IPsec处理的流,会被指向到一个template。一个template可以理解为指向一个SA,template包含以下属性:

  • 协议

    • AH或ESP。
  • 模式
    • transport或tunnel模式。
  • pattern
    • 源IP加目的IP对。
    • NAT的PORT对。

SP有一个方向属性,取值分别为:

  • out
  • in
  • fwd

1.5 总结

在整个IPsec的数据流转逻辑中,SP用来表达What todo。SA用来表达How todo。


2 数据流

简单的说。明文报在通过IPsec VPN设备变成ESP发出去的过程是:

  1. 查找路由。
  2. 查找policy决定是否需要被ESP
  3. 查找SA并加密封装。
  4. 加密封装后的包再查路由。

IPsec报在通过IPsec VPN设备变成非加密包发出去的过程:

  1. 查找路由。
  2. 查找policy决定是否需要要解ESP
  3. 查找SA并解密解封装。
  4. 解密解封装后的包再查路由。

2.1 举个栗子

路由

[root@T9 sbin]# ip route
default via 192.168.7.1 dev eth0 proto static metric 100
10.129.0.0/24 dev eth1 proto kernel scope link src 10.129.0.1 metric 100
192.168.7.0/24 dev eth0 proto kernel scope link src 192.168.7.129 metric 100

policy

[root@T9 sbin]# ip xfrm policy
src 10.9.0.0/16 dst 10.129.0.0/16
dir fwd priority 383616 ptype main
tmpl src 192.168.7.9 dst 192.168.7.129
proto esp reqid 1 mode tunnel
src 10.9.0.0/16 dst 10.129.0.0/16
dir in priority 383616 ptype main
tmpl src 192.168.7.9 dst 192.168.7.129
proto esp reqid 1 mode tunnel
src 10.129.0.0/16 dst 10.9.0.0/16
dir out priority 383616 ptype main
tmpl src 192.168.7.129 dst 192.168.7.9
proto esp reqid 1 mode tunnel

sa

[root@T9 sbin]# ip xfrm state
src 192.168.7.129 dst 192.168.7.9
proto esp spi 0xc42ac7f3 reqid 1 mode tunnel
replay-window 0 flag af-unspec
auth-trunc hmac(sha256) 0x5f7b99e.....eb20948fb2f8fc713caf2d43b4 128
enc cbc(aes) 0x48144872d5f4f9a6a762b68785e6f265
src 192.168.7.9 dst 192.168.7.129
proto esp spi 0xc1c8ad99 reqid 1 mode tunnel
replay-window 32 flag af-unspec
auth-trunc hmac(sha256) 0x7efc5d2172.....0c0dedf053b0b6ae5aa2f012 128
enc cbc(aes) 0x808efcfaa45a543b69efe08158accaa3

3 理解linux kernel中的sa概念和管理

3.1 提供给用户的sa接口

理解kernel sa对用户展示的形态,可以帮助我们理解linux kernel对于ipsec sa的建模和抽象。对我们在VPN产品的sa模块设计中将提供帮助。

3.1.1 使用racoon配置sa

setkey add 192.168.0.1 192.168.1.2 esp 0x10001
-m tunnel
-E des-cbc 0x3ffe05014819ffff
-A hmac-md5 "authentication!!"

从以上信息可以很容易开始各个参数表达的含义,其中-E代表加密算法和它的key,-A代表验证算法和它的key。0x10001为spi。

3.1.2 使用racoon配置policy

setkey spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any
-P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require

第一行代表五元组,any代表协议。第二行代表policy的具体描述:方向,action,template。

3.1.3 总结

通过以上两个小节的描述,读者应该已经很容易的总结出了配置一个SA和一个policy所需要提供的最基本的信息了。作者将在本章的最后,对sa和poliyc所包含的所有必须信息进行一个统一的总结。

另外,通过上文的语法,我们应该能够发现,policy与sa之间的match操作,是需要一个稍负责的匹配逻辑来实现的,而不仅仅是一个简单的匹配关系。

3.2 netlink的SA接口

strongswan是目前使用两种方式与内核进行ipsec的配置交互,分别为netlink和pfkey。如官方文档所述,netlink是strongswan默认启用的,变成stable的接口方式。整个调研工作也是以netlink方式为出发点展开的,现简单介绍如下。

3.2.1 什么是netlink

netlink是复用了socket方式的内核与用户态IPC方法。

这里有一篇写的非常好的文章,讲netlink为什么会产生。由于人家写的实在是太好了,我已经没有什么可写的了,只能做个概要,如下:



因为作者图画是业余的,所以看懂的这个概要图的前提是,你必须懂得BSD socket的api如何使用。

3.2.2 接口方式

用netlink方式配置ipsec的方法。

netlink的一般用法
初始化socket

与常规的socket用法相同,只是传入参数是netlink定义的特有参数。

int socket(int domain, int type, int protocol)
bind(fd, (struct sockaddr*)&nladdr, sizeof(nladdr));
下发配置信息到kernel

使用socket的标准send,write接口将特定格式的参数下发给kernel。

参数格式如下:

struct nlmsghdr
{
__u32 nlmsg_len; /* Length of message */
__u16 nlmsg_type; /* Message type*/
__u16 nlmsg_flags; /* Additional flags */
__u32 nlmsg_seq; /* Sequence number */
__u32 nlmsg_pid; /* Sending process PID */
};

这个参数结构体是传入参数的头部,紧接着这个头部之后的内存是真正的参数的值。它的解析方法由nlmsg_type的值来确定。它的结尾由nlmsg_len的数值来决定。

添加sa

添加sa的时候,nlmsghdr后面的参数为结构体

struct xfrm_usersa_info

nlmsg_type的值为:XFRM_MSG_NEWSA

这部分内容定义在系统文件下:

/usr/include/linux/xfrm.h

这个结构体后边,还需要追加算法部分的信息,如下:

struct xfrm_algo
struct xfrm_algo_auth
添加policy

添加policy的时候,nlmsghdr后面的参数为结构体

struct xfrm_userpolicy_info

nlmsg_type的值为:XFRM_MSG_NEWPOLICY

这部分内容定义在系统文件下:

/usr/include/linux/xfrm.h

3.3 xfrm的SA接口

3.3.1 什么是xfrm

xfrm(transform)是一个IP包转发框架。主要实现以下三部分功能:

  • IPsec protocol suite
  • IP Payload Compression Protocol
  • Mobile IPv6

3.3.2 内核代码

linux/net/xfrm/

主要函数

Xfrm_lookup()            xfrm lookup(SPD and SAD) method
Xfrm_input() xfrm processing for an ingress packet
Xfrm_output() xfrm processing for an egress packet
Xfrm4_rcv() IPv4 specific Rx method
Xfrm6_rcv() IPv6 specific Rx method
Esp_input() ESP processing for an ingress packet
Esp_output() ESP processing for an egress packet
Ah_output() AH processing for an ingress packet
Ah_input() ESP processing for an egress packet
xfrm_policy_alloc() allocates an SPD object
Xfrm_policy_destroy() frees an SPD object
xfrm_ policy_lookup SPD lookup
xfrm_policy_byid() SPD lookup based on id
Xfrm_policy_insert() Add an entry to SPD
Xfrm_Policy_delete() remove an entry from SPD
Xfrm_bundle_create() creates a xfrm bundle
Xfrm_policy_delete() releases the resources of a policy object
Xfrm_state_add() add an entry to SAD
Xfrm_state_delete() free and SAD object
Xfrm_state_alloc() allocate an SAD object
xfrm_state_lookup_byaddr() src address based SAD lookup
xfrm_state_find() SAD look up based on dst
xfrm_state_lookup() SAD lookup based on spi

3.3.3 API

api文件

include/uapi/linux/xfrm.h

主要的API

XFRM_MSG_NEWSA         To add a new SA to SAD
XFRM_MSG_DELSA To delete a new SA to SAD
XFRM_MSG_GETSA To get a new SA to SAD
XFRM_MSG_FLUSHSA To flush SAD
XFRM_MSG_NEWPOLICY To add a new policy to SPD
XFRM_MSG_DELPOLICY To delete a new policy to SPD
XFRM_MSG_GETPOLICY To get a new policy to SPD
XFRM_MSG_FLUSHPOLICY To flush SPD

3.3.4 sa的传入参数

struct xfrm_usersa_info {
struct xfrm_selector sel; // 被加密网段?为啥要有这个?
struct xfrm_id id; // 目的ip,spi,协议ah/esp
xfrm_address_t saddr; // 源ip
struct xfrm_lifetime_cfg lft;
struct xfrm_lifetime_cur curlft;
struct xfrm_stats stats;
__u32 seq;
__u32 reqid;
__u16 family;
__u8 mode; // transport / tunnel
__u8 replay_window;
__u8 flags;
};

算法参数是追加在SA结构体之后的内存块,根据不同的类型决定不同的结构。示例:

struct xfrm_algo {
char alg_name[64];
unsigned int alg_key_len; /* in bits */
char alg_key[0];
}; struct xfrm_algo_auth {
char alg_name[64];
unsigned int alg_key_len; /* in bits */
unsigned int alg_trunc_len; /* in bits */
char alg_key[0];
};

3.3.5 policy的传入参数

struct xfrm_userpolicy_info {
struct xfrm_selector sel; //网段:ip,port,协议
struct xfrm_lifetime_cfg lft;
struct xfrm_lifetime_cur curlft;
__u32 priority; //
__u32 index;
__u8 dir; //方向:in out fwd
__u8 action; // allow, block
__u8 flags;
__u8 share;
};

4 xfrm的实现

4.1 用于存储sa的内部数据结构

struct xfrm_state {
#ifdef CONFIG_NET_NS
struct net *xs_net;
#endif
union {
struct hlist_node gclist;
struct hlist_node bydst;
};
struct hlist_node bysrc;
struct hlist_node byspi;
atomic_t refcnt;
spinlock_t lock;
struct xfrm_id id;
struct xfrm_selector sel;
struct xfrm_mark mark;
u32 tfcpad;
u32 genid;
/* Key manager bits */
struct xfrm_state_walk km;
/* Parameters of this state. */
struct {
u32 reqid;
u8 mode;
u8 replay_window;
u8 aalgo, ealgo, calgo;
u8 flags;
u16 family;
xfrm_address_t saddr;
int header_len;
int trailer_len;
u32 extra_flags;
} props;
struct xfrm_lifetime_cfg lft;
/* Data for transformer */
struct xfrm_algo_auth *aalg;
struct xfrm_algo *ealg;
struct xfrm_algo *calg;
struct xfrm_algo_aead *aead;
/* Data for encapsulator */
struct xfrm_encap_tmpl *encap;
/* Data for care-of address */
xfrm_address_t *coaddr;
/* IPComp needs an IPIP tunnel for handling uncompressed packets */
struct xfrm_state *tunnel;
/* If a tunnel, number of users + 1 */
atomic_t tunnel_users;
/* State for replay detection */
struct xfrm_replay_state replay;
struct xfrm_replay_state_esn *replay_esn;
/* Replay detection state at the time we sent the last notification */
struct xfrm_replay_state preplay;
struct xfrm_replay_state_esn *preplay_esn;
/* The functions for replay detection. */
struct xfrm_replay *repl;
/* internal flag that only holds state for delayed aevent at the
* moment
*/
u32 xflags;
/* Replay detection notification settings */
u32 replay_maxage;
u32 replay_maxdiff;
/* Replay detection notification timer */
struct timer_list rtimer;
/* Statistics */
struct xfrm_stats stats;
struct xfrm_lifetime_cur curlft;
struct tasklet_hrtimer mtimer;
/* used to fix curlft->add_time when changing date */
long saved_tmo;
/* Last used time */
unsigned long lastused;
/* Reference to data common to all the instances of this
* transformer. */
const struct xfrm_type *type;
struct xfrm_mode *inner_mode;
struct xfrm_mode *inner_mode_iaf;
struct xfrm_mode *outer_mode;
/* Security context */
struct xfrm_sec_ctx *security;
/* Private data of this transformer, format is opaque,
* interpreted by xfrm_type methods. */
void *data;
};

会被插入两个hash表

   1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
2. Hash table by (daddr,family,reqid) to find what SAs exist for given
destination/tunnel endpoint. (output)

4.2 用于存储sa的内部数据结构

struct xfrm_policy {
#ifdef CONFIG_NET_NS
struct net *xp_net;
#endif
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];
};

4.3 数据结构之间的存储结构

TODO

4.4 关键函数

xfrm_lookup()
xfrm_output()
xfrm4_policy_check() // 在ipv4中被调用。

5 strongswan中的sa

5.1 概述

从IKE协议的角度上,有两个SA,一个叫IKE_SA,一个叫CHILD_SA。本章讨论的sa,特指下图中的CHILD_SA。

本篇文章,通篇讨论的SA指的都是这里的CHILD_SA。

CHILD_SA在strongswan的框架里,主要存在与两个部分。

  1. IKE协商过程。

    CHILD_SA是IKE协商过程中的输出。IKE协商过程结束后,IKE-SA Manager将CHILD_SA交个strongswan框架。
  2. IPsec隧道建立过程。

    CHILD_SA是IKE协商过程中的输入。strongswan框架将CHILD_SA交给libcharon plugin由特定的plugin与kernel通信,在kernel中完成IPsec tunnel的建立过程。
  3. IPsec在转发过程。

    这部分和strongswan的框架没有了关系,由内核完成。
      +---------------------------------+       +----------------------------+
| Credentials | | Backends |
+---------------------------------+ +----------------------------+ +------------+ +-----------+ +------+ +----------+
| receiver | | | | | +------+ | CHILD_SA |
+----+-------+ | Scheduler | | IKE- | | IKE- |--+----------+
| | | | SA |--| SA | | CHILD_SA |
+-------+--+ +-----------+ | | +------+ +----------+
<->| socket | | | Man- |
+-------+--+ +-----------+ | ager | +------+ +----------+
| | | | | | IKE- |--| CHILD_SA |
+----+-------+ | Processor |--------| |--| SA | +----------+
| sender | | | | | +------+
+------------+ +-----------+ +------+ +---------------------------------+ +----------------------------+
| Bus | | Kernel Interface |
+---------------------------------+ +----------------------------+
| | |
+-------------+ +-------------+ V
| File-Logger | | Sys-Logger | //////
+-------------+ +-------------+

5.1.1 strongswan中的plugin

上一小节提到了plugin,接下来讲解plugin

有两类plugins。一类是libstrongswan的plugin,一类是libcharon的plugin

libstrongswan的plugin主要提供加密,认证,数据库相关的功能。

libcharon的plugin主要提供“specific needs”。。。我们接下来要讨论的与sa下发相关的plugin都在

libcharon这一类里。他们包括:

  • kernel-libipsec

    用户态的转发平面,目前还处于高实验性阶段。转发性能没有kernel。主要用来满足不能使用kernel转发的场景。
  • kernel-netlink

    使用netlink接口与linux kernel的xfrm模块交互。目前输出稳定使用阶段,默认首选。
  • kernel-iph

    windows操作系统的接口。
  • kernel-pfkey

    使用pkkey接口与linux kernel的xfrm模块进行交互,高实验性阶段。
  • kernel-wfp

    windows操作系统的接口。

本文,只关心kernel-netlink的plugin。

5.2 启动过程

5.2.1 概述

strongswan的启动方式有多种。可以和各种不同的系统对接,包括systemd,networkmanager等。

  • starter

    ipsec命令使用的守护进程。用ipsec start命令,就会启动这个进程。
  • charon-nm

    networkmanager的plugin。什么是nm的plugin?
  • charon-systemd

    按照systemd的daemon style实现的一个进程。由systemd启动。
  • charon-svc

    windows的服务。

各种启动方式的最终目的都是启动最终目的都是启动charon进程。所以,最简的启动方法就是:

  • 直接运行charon进程

当然,这种方式没有daemon守护,但是功能完整。

5.2.2 调试方法

如上一小节所述。charon进程可以直接运行。所以调试的时候直接使用gdb运行charon就可以了。

# gdb `which charon`

5.2.3 starter的启动过程

starter的启动方法是通过ipsec脚本执行start命令,这样便启动了strongswan服务。

# ipsec start
ipsec脚本

源码位置

strongswan-5.7.1/src/ipsec/_ipsec

ipsec脚本解析start参数后,会执行如下命令,启动daemon进程starter

${IPSEC_DIR}/starter --daemon charon
starter进程

源码位置

strongswan-5.7.1/src/starter/starter.c

starter的主要功能是启动charon进程,并进行守护。

  • daemon的初始工作

    重定向输出,signal响应等。
  • 启动charon
  • 加载ipsec.conf中的配置。
流程图

charon进程

charon进程运行启动成功后,启动16个子线程执行不同的job。

整个charon中的任务调度围绕着task和job两个核心概念进行。

流程图

实线代表流程图;虚线代表调用栈。

5.2.4 systemd的启动过程

systemd的启动过程首先使用systemd的service配置脚本。然后启动systemd的charon守护进程。

最后通过守护进程启动charon进程。

systemd脚本

源码位置

strongswan-5.7.1/init/systemd-swanctl/strongswan-swanctl.service.in

service脚本在启动过程执行两个操作。

  1. 启动charon-systemd进程。
  2. 执行swanctl --load-all --noprompt命令
charon-systemd进程

源码位置

strongswan-5.7.1/src/charon-systemd/charon-systemd.c

charon-systemd进程是charon进程的另一个入口。charon-systemd进程不会在启动新的进程,charon-systemed进程就是处理业务的主进程,有systemd进行守护。

所以,charon-systemd只有main函数中的少量内容与charon不同。其他逻辑与charon进程完全相同。

流程图

5.3 调用过程

运行过程中,与SA相关的两个部分主要就是add_sa与add_policy两个地方。

当charon进程收到一个message的时候,会以job的形式分发给standby的业务线程进行处理。

最后通过kernel对象调用kernel_interface接口中的add_sa和add_policy两个函数。接口会根据

具体注册的plugin调用各plugin的相应,add_as, add_policy函数。

例如,netlink的plugin。

在该plugin的这两个函数中,会通过netlink的接口最终调用内核的xfrm接口完成sa和policy的下发和更新等操作。

详见3.2和3.3两个章节。

5.4 数据结构

strongswan中的sa数据结构

定义在文件 kernel_ipsec.h 中,由id和data两个结构共同组成。

struct kernel_ipsec_sa_id_t {
/** Source address */
host_t *src;
/** Destination address */
host_t *dst;
/** SPI */
uint32_t spi;
/** Protocol (ESP/AH) */
uint8_t proto;
/** Optional mark */
mark_t mark;
}; /**
* Data required to add an SA to the kernel
*/
struct kernel_ipsec_add_sa_t {
/** Reqid */
uint32_t reqid;
/** Mode (tunnel, transport...) */
ipsec_mode_t mode;
/** List of source traffic selectors */
linked_list_t *src_ts;
/** List of destination traffic selectors */
linked_list_t *dst_ts;
/** Network interface restricting policy */
char *interface;
/** Lifetime configuration */
lifetime_cfg_t *lifetime;
/** Encryption algorithm */
uint16_t enc_alg;
/** Encryption key */
chunk_t enc_key;
/** Integrity protection algorithm */
uint16_t int_alg;
/** Integrity protection key */
chunk_t int_key;
/** Anti-replay window size */
uint32_t replay_window;
/** Traffic Flow Confidentiality padding */
uint32_t tfc;
/** IPComp transform */
uint16_t ipcomp;
/** CPI for IPComp */
uint16_t cpi;
/** TRUE to enable UDP encapsulation for NAT traversal */
bool encap;
/** no (disabled), yes (enabled), auto (enabled if supported) */
hw_offload_t hw_offload;
/** Mark the SA should apply to packets after processing */
mark_t mark;
/** TRUE to use Extended Sequence Numbers */
bool esn;
/** TRUE to copy the DF bit to the outer IPv4 header in tunnel mode */
bool copy_df;
/** TRUE to copy the ECN header field to/from the outer header */
bool copy_ecn;
/** Whether to copy the DSCP header field to/from the outer header */
dscp_copy_t copy_dscp;
/** TRUE if initiator of the exchange creating the SA */
bool initiator;
/** TRUE if this is an inbound SA */
bool inbound;
/** TRUE if an SPI has already been allocated for this SA */
bool update;
};

strongswan中的policy数据结构

定义在文件 kernel_ipsec.h 和 ipsec_types.h 中。

struct kernel_ipsec_policy_id_t {
/** Direction of traffic */
policy_dir_t dir;
/** Source traffic selector */
traffic_selector_t *src_ts;
/** Destination traffic selector */
traffic_selector_t *dst_ts;
/** Optional mark */
mark_t mark;
/** Network interface restricting policy */
char *interface;
}; /**
* Data required to add/delete a policy to/from the kernel
*/
struct kernel_ipsec_manage_policy_t {
/** Type of policy */
policy_type_t type;
/** Priority class */
policy_priority_t prio;
/** Manually-set priority (automatic if set to 0) */
uint32_t manual_prio;
/** Source address of the SA(s) tied to this policy */
host_t *src;
/** Destination address of the SA(s) tied to this policy */
host_t *dst;
/** Details about the SA(s) tied to this policy */
ipsec_sa_cfg_t *sa;
}; struct ipsec_sa_cfg_t {
/** mode of SA (tunnel, transport) */
ipsec_mode_t mode;
/** unique ID */
uint32_t reqid;
/** number of policies of the same kind (in/out/fwd) attached to SA */
uint32_t policy_count;
/** details about ESP/AH */
struct {
/** TRUE if this protocol is used */
bool use;
/** SPI for ESP/AH */
uint32_t spi;
} esp, ah;
/** details about IPComp */
struct {
/** the IPComp transform used */
uint16_t transform;
/** CPI for IPComp */
uint16_t cpi;
} ipcomp;
};

6 sa的抽象模型

6.1 实现sa管理的思路

略。

6.2 sa

目的地址(dip)加 spi 唯一确定一个sa条目。

属性 取值 说明
id
spi 协商过程带过来的
mode transport/tunnel
protocol esp/ah/ipcom 加密协议的方式
sip 另一条隧道是sip和dip互换的,故两个sa
dip
life 生存时间
enc_alg
enc_key
integrity_alg 完整性验证
integrity_key
nat 是否做nat

6.3 policy

属性 取值 说明
id
action drop/pass/ipsec 命中此策略后的行为
priority 优先级
dir in/out/fwd 方向
s_ts source traffic selector
d_ts destination traffic selector

6.4 traffic selector

ts就是五元组,ip使用掩码掩起来的一个段。port也可以掩,具体跟kernel学一下。

属性 说明
source ip
sip_prefixlen
dest ip
dip_prefixlen
sport
sport_mask
dport
dport_mask
protocol

7 问题

7.1 policy与路由的关系

在我的测试虚机环境里,删掉了策略路由之后,功能正常。

目前还不清楚为什么。路由与policy之间的关系,以及路由和policy在内核包转发过程中的逻辑关系,

都需要进一步的调研。

7.2 policy与sa之间的关联逻辑


参考

http://man7.org/linux/man-pages/man8/ip-xfrm.8.html

最新文章

  1. 真实记录疑似Linux病毒导致服务器 带宽跑满的解决过程
  2. JavaBean的用法
  3. 用sql取出来的list需要处理成map的两种情况
  4. JSON字符串与java对象的转换
  5. Android 标签的主题样式
  6. iOS开发多线程篇—线程间的通信(转)
  7. 洗清UI自动化鸡肋说的不白之冤
  8. 通用权限底层研究:Web应用限制IP访问的功能实现
  9. 72. Edit Distance
  10. Winxp下搭建SVN服务器
  11. 3.x vector的用法
  12. WebService的基本介绍
  13. wait和notify的理解与使用
  14. 关于jquery日期控件及时间格式转换2017.05.27
  15. DevOps实例
  16. 关于wordpress慢的问题
  17. Centos6.5搭建Elasticsearch
  18. Neo4j学习笔记
  19. Spring Boot + Spring Cloud 构建微服务系统(六):熔断监控集群(Turbine)
  20. Java 8 – Period and Duration examples

热门文章

  1. oracle sequnece 介绍以及 监控
  2. 报错:ImportError: cannot import name &quot;KafkaProducer&quot; from &quot;kafka&quot;
  3. 如何优化代码和RAM大小
  4. 通过ssh登录到手机 Termux
  5. [LeetCode] 293. Flip Game 翻转游戏
  6. Java面试题大汇总(附答案)
  7. laravel composer vendor 目录加载类库详细 之后做说明
  8. vs2010+ARX2012向导添加mfc支持类出现Error in default.htm PopulateDialogIDs():
  9. k8s 修改节点角色和删除节点
  10. STM32F030-UART1_DMA使用提示