Netfilter的table和rule(2)

上一章讲解Netfilter的hook点知识及源代码分析
小伙伴了解到报文在内核网络栈会经过5个hook点,每个hook点会安装若干个钩子函数,报文经过每个hook点时会有序的调用钩子函数处理,而钩子函数处理时需要table的rule。问题就来了,钩子函数和rule是怎么联系起来;rule是如何归属于table呢;iptables命令如何下发rule到netfilter模块的;

1.table描述

在内核中代表table的结构体:xt_table,该结构维护了哪些hook点有效,属于哪个协议族(ipv4/ipv6),属于该table的所有规则以及所在有效的hook点上的执行优先级。
Netfiler的table结构
Netfilter框架会在每个net ns创建时,创建默认rule关联到table的private属性里,然后把table信息和table的构子函数,记录到net ns里(struct net)。

filter table 注册

2.rule描述

2.1 默认rule

在系统启动后,每张table注册的时候,默认生成一条”放行“的rule,保证在某条hook点上所有rule不匹配后都”放行“。
可以通过iptables命令查看某张表的hook点上的默认rule。

命令: iptables -t filter -vnL

Chain INPUT (policy DROP 8036 packets, 606K bytes)
Chain FORWARD (policy ACCEPT 32691 packets, 13M bytes)
 pkts bytes target     prot opt in     out     source               destination         
Chain OUTPUT (policy ACCEPT 8110 packets, 764K bytes)
 pkts bytes target     prot opt in     out     source               destination        
2.2下发rule

Netfilter采用sockopt方式,是一种内核和用户空间通信手段之一。
socket方式的SET接口约定使用struct ipt_replace结构体下发rule。

/* The argument to IPT_SO_SET_REPLACE. */
struct ipt_replace {
	/* Which table. */
	char name[XT_TABLE_MAXNAMELEN];			/*要更新的table*/

	/* Which hook entry points are valid: bitmask.  You can't
           change this. */
	unsigned int valid_hooks;				/*哪些hook点有效*/

	/* Number of entries */
	unsigned int num_entries;				/*rule数量*/

	/* Total size of new entries */
	unsigned int size;						/*rule数量的总大小*/

	/* Hook entry points. */
	unsigned int hook_entry[NF_INET_NUMHOOKS];	/*记录每个hook的第一条rule的位置*/

	/* Underflow points. */
	unsigned int underflow[NF_INET_NUMHOOKS];   /*记录每个hook的最后一条rule的位置*/
	
	/* Information about old entries: */
	/* Number of counters (must be equal to current number of entries). */
	unsigned int num_counters;   /*报文数量*/
	/* The old entries' counters. */
	struct xt_counters *counters; /*报文统计*/

	/* The entries (hang off end: not really an array). */
	struct ipt_entry entries[0];				/*所有rule的存储位置,每个hook的所有rule位置是连续的*/
};

iptables命令采用该通信方法下发rule,该命令的配置思想:读->更新->写 方式,先获取某个table的所有rule,再对具体操作(删除/插入/…)更新或者新增rule,完成之后所有rule重新下发到Netfilter,整个过程可以理解为 “全量替换“。
sockopt方式下发rule
以及基于struct ipt_replace结构存储所有rule的内存布局如下:
rule是连续存储的,按照hook定义的编号从小到大排列(pre_routing < input < forward < output < post_routing )。
hook_entry和underflow记录了每个hook的所有rule的起始位置和结束位置。
rule在ipt_replace内存分布

2.3rule的结构体

无论在内核还是用户空间环境下,一条rule的具体信息是存储在ipt_entry结构体里。
它的elems属性包含0个或者多个ipt_entry_match结构体和一个ipt_entry_target结构体。

/* This structure defines each of the firewall rules.  Consists of 3
   parts which are 1) general IP header stuff 2) match specific
   stuff 3) the target to perform if the rule matches */
struct ipt_entry {
	struct ipt_ip ip;

	/* Mark with fields that we care about. */
	unsigned int nfcache;

	/* Size of ipt_entry + matches */
	__u16 target_offset;
	/* Size of ipt_entry + matches + target */
	__u16 next_offset;

	/* Back pointer */
	unsigned int comefrom;

	/* Packet and byte counters. */
	struct xt_counters counters;

	/* The matches (if any), then the target. */
	unsigned char elems[0];
};

ipt_entry具有标准匹配信息,包含网口、ip地址信息等
ipt_entry_match具有扩展匹配信息,包含TCP状态、端口范围信息等
ipt_entry_target代表匹配信息完成后,采用哪种行为,如放行、丢弃或者跳转等。

match、target分为标准和扩展,这些概念自行补补。

rule组成部分

3.table和rule最终形态

table从注册到形成,rule从一条默认rule逐渐增多,最后它们会存储在每个net ns里,提供给netfilter使用。
table和rule最终形态

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值