Netfilter中rule的match(3)

上一章讲解Netfilter的table和rule知识

每一条rule包含着matchtarget两部分信息,该章节主要讲解rule其中match部分。报文经过Netfilter框架注册的hook时,会把该hook中table的rule逐条执行,若是命中某条rule的match部分,则会执行该rule的target动作。hook的整个处理周期,就是围绕着rule的这两部分转。

rule组成部分

1. 扩展match部分条件信息的表示

match部分 分为 标准扩展,它们代表的方式不一,前者的信息存储在ipt_entry中,包含网口、源地址、目的地址等信息,且只有一份;后者可以有0个或者多个match部分,可拥有多份;它使用ipt_entry_match结构体表示,ipt_entry_match是别名(讲解使用该昵称),真实的名称为xt_entry_match。

iptable_entry_match属性中采用了union方式共用同一块内存,来划分不同角度的配置,使用userkernel属性表示用户空间和内核空间,在用户空间时需要一个模块的名称和该模块的match数据,它们分别存放在user.name和user.data[0]里。rule规则到达内核空间时,会根据name去netfilter框架中寻找已经注册好的match模块,并记录找到的match模块的位置,存储到kernel.match属性。

struct xt_entry_match {
	union {
		struct {
			__u16 match_size;

			/* Used by userspace */
			char name[XT_EXTENSION_MAXNAMELEN]; /*match模块的名称, 如tcp、udp等模块名称*/
			__u8 revision;
		} user;
		struct {
			__u16 match_size;

			/* Used inside the kernel */
			struct xt_match *match;
		} kernel;

		/* Total length */
		__u16 match_size;/*XT_ALIGN(sizeof(struct xt_entry_match)) + XT_ALIGN(data);*/
	} u;

	unsigned char data[0];
};

match条件信息和关联的match模块

2. 注册扩展match模块

上面讲到的match模块,它是预先注册到netfilter框架中,在后续的rule的match条件信息中会使用到。若是没有注册的话,会被检查出来的。

iptables命令使用match模块时可以显式声明(-m tcp/ -m udp)或者隐式声明使用-p tcp时,会自动找到对应的match模块。

xt_match结构体代表着一个扩展match模块;
其中:
name是该扩展match模块名称;
match函数会在报文经过hook点时调用,若报文匹配成功返回true, 否则为false;
checkentry函数会在配置rule时对具体数据进行检验(指的是ipt_entry_match.data[0]属性),检验成功返回0, 否则返回非0;
destroy函数在配置rule时,如若有一个ipt_entry_match找不到match模块会被调用,销毁相应的资源;

struct xt_match {
	struct list_head list;

	const char name[XT_EXTENSION_MAXNAMELEN];
	u_int8_t revision;

	/* Return true or false: return FALSE and set *hotdrop = 1 to
           force immediate packet drop. */
	/* Arguments changed since 2.6.9, as this must now handle
	   non-linear skb, using skb_header_pointer and
	   skb_ip_make_writable. */
	bool (*match)(const struct sk_buff *skb,
		      struct xt_action_param *);

	/* Called when user tries to insert an entry of this type. */
	int (*checkentry)(const struct xt_mtchk_param *);

	/* Called when entry of this type deleted. */
	void (*destroy)(const struct xt_mtdtor_param *);

	...
	
	unsigned short family;
};

常用的match模块有tcp、udp,实现的部分在内核源码的xt_tcpudp.c文件中定义。
tcp和udp的扩展match模块
所有扩展match模块,需要通过xt_register_matches接口注册,最终存放在xt[NFPROTO_NUMPROTO]数组变量中。

static struct xt_af *xt;

struct xt_af {
	struct mutex mutex;
	struct list_head match;/*存储扩展match模块*/
	struct list_head target;
#ifdef CONFIG_COMPAT
	struct mutex compat_mutex;
	struct compat_delta *compat_tab;
	unsigned int number; /* number of slots in compat_tab[] */
	unsigned int cur; /* number of used slots in compat_tab[] */
#endif
};

xt维护各个扩展模块
配置rule下发内核空间时,会通过以下流程图,最终通过xt[NFPROTO_IPV4]数组变量找到match模块。
查找match模块流程

static int
find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
	struct xt_match *match;
	int ret;

	/*从xt[NFPROTO_IPV4]中查找match模块*/
	match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
				      m->u.user.revision);
	if (IS_ERR(match))
		return PTR_ERR(match);
	m->u.kernel.match = match;/*找到name对应的match模块*/

	ret = check_match(m, par);/*把配置参数传给match模块校验*/
	if (ret)
		goto err;

	return 0;
err:
	module_put(m->u.kernel.match->me);
	return ret;
}

4.使用扩展match模块

报文经过的hook时,会调用各自table安装的钩子函数,最终会调用ipt_do_table函数进行匹配和决定行为。

filter table -> iptable_filter_hook
nat table -> iptable_nat_do_hook
mangle table -> iptable_mangle_hook
raw -> iptable_raw_hook

/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned int
ipt_do_table(struct sk_buff *skb,
	     const struct nf_hook_state *state,
	     struct xt_table *table)
{
	...
	
	do {
		...
		const struct xt_entry_match *ematch;
		...

		WARN_ON(!e);
		if (!ip_packet_match(ip, indev, outdev,
		    &e->ip, acpar.fragoff)) { /*标准match部分: match条件不符合,则检查下一条rule*/
 no_match:
			e = ipt_next_entry(e);
			continue;
		}
		/*扩展match部分, 每条rule和报文进行匹配*/
		xt_ematch_foreach(ematch, e) {
			acpar.match     = ematch->u.kernel.match;
			acpar.matchinfo = ematch->data;
			if (!acpar.match->match(skb, &acpar))
				goto no_match;/*某条match条件信息不符合,则检查下一条rule*/
		}

		...
}

ipt_do_table
以上源代码以及内容基于内核4.19.1产出。

—越简单,易接受。在折腾路上…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值