Linux系统中防火墙的框架及简单分析

netfilter提供了个抽象、通用化框架该框架定义个子功能实现就是包过滤子系统框架包含以下 5部分: 1. 为每种网络协议(ipv4、ipv6等)定义套钩子(ipv4定义了5个钩子), 这些钩子在数据报流过协议栈几个关键点被在这几个点中协议栈将把数据报及钩子标号作为参数netfilter框架 2. 内核任何模块可以对每种协议个或多个钩子进行注册实现挂接这样当某个数据包被传递给netfilter框架时内核能检测是否有任何模块对该协议和钩子进行了注册若注册了该模块注册时使用回调这样这些模块就有机会检查(可能还会修改)该数据包、丢弃该数据包及指示netfilter将该数据包传入用户空间队列 3 .那些排队数据包是被传递给用户空间异步地进行处理个用户进程能检查数据包修改数据包甚至可以重新将该数据包通过离开内核个钩子中注入到内核中 4. 任何在ip层要被抛弃ip数据包在真正抛弃的前都要进行检查例如允许模块检查ip-spoofed包(被路由抛弃) 5.ip层 5个hook点位置如下所示 : (1)nf_ip_pre_routing:刚刚进入网络层数据包通过此点(刚刚进行完版本号校验 和等检测) 源地址转换在此点进行;ip_input.c中ip_rcv (2)nf_ip_local_in:经路由查找后送往本机通过此检查点,input包过滤在此点进行;ip_local_deliver中 (3)nf_ip_forward:要转发包通过此检测点,forword包过滤在此点进行; (4)nf_ip_post_routing:所有马上便要通过网络设备出去包通过此检测点内置地址转换功能(包括地址伪装)在此点进行; (5)nf_ip_local_out:本机进程发出包通过此检测点output包过滤在此点进行 这些点是已经在内核中定义好内核模块能够注册在这些hook点进行处理可使用nf_register_hook指定在数据报经过这些钩子时被从而模块可以修改这些数据报并向netfilter返回如下值: nf_accept 继续正常传输数据报 nf_drop 丢弃该数据报不再传输 nf_stolen 模块接管该数据报不要继续传输该数据报 nf_queue 对该数据报进行排队(通常用于将数据报给用户空间进程进行处理) nf_repeat 再次该钩子 个基于netfilter框架、称为iptables数据报选择系统在linux2.4内核中被应用其实它就是ipchains后继工具但却有更强可扩展性内核模块可以注册个新规则表(table)并要求数据报流经指定规则表这种数据报选择用于实现数据报过滤(filter表)网络地址转换(nat表)及数据报处理(mangle表) linux2.4内核提供这 3种数据报处理功能都基于netfilter钩子和ip表它们是独立模块相互的间是独立它们都完美集成到由netfileter提供框架中 包过滤 filter表格不会对数据报进行修改而只对数据报进行过滤iptables优于ipchains个方面就是它更为小巧和快速它是通过钩子nf_ip_local_in, nf_ip_forward及nf_ip_local_out接入netfilter框架因此对于任何个数 报只有个地方对其进行过滤这相对ipchains来说是个巨大改进在ipchains中个被转发数据报会遍历 3条链 nat nat表格监听 3个netfilter钩子:nf_ip_pre_routing、nf_ip_post_routing及nf_ip_local_out nf_ip_pre_routing实现对需要转发数据报源地址进行地址转换而nf_ip_post_routing则对需要转发数据包地址进行地址转换对于本地数据报地址转换则由nf_ip_local_out来实现nat表格区别于filter表格只有新连接个数据报将遍历表格而随后数据报将根据第个数据报结果进行同样转换处理nat表格被用在源nat,目nat伪装(其是源nat个特例)及透明代理(其是目nat个特例) 数据报处理(packet mangling) mangle表格在nf_ip_pre_routing和nf_ip_local_out钩子中进行注册使用 mangle表可以实现对数据报修改或给数据报附上些带外数据当前mangle表支持修改tos位及设置skbnfmard字段 源码分析 如果我们想加入自己代码,便要用nf_register_hook原型为:
nf_register_hook(struct nf_hook_ops *reg) struct nf_hook_ops { struct list_head list; /* user fills in from here down. */ nf_hookfn *hook; pf; hooknum; /* hooks are ordered in ascending priority. */ priority; };



我们工作便是生成个struct nf_hook_ops结构例子并用nf_register_hook将其hook上其中list项我们总要化为{null,null};由于般在ip层工作pf总是pf_inet;hooknum就是我们选择hook点;个hook点可能挂多个处理谁先谁后便要看优先级即priority指定了netfilter_ipv4.h中用个枚举类型指定了内置处理优先级:
enum nf_ip_hook_priorities { nf_ip_pri_first = _min, nf_ip_pri_conntrack = -200, nf_ip_pri_mangle = -150, nf_ip_pri_nat_dst = -100, nf_ip_pri_filter = 0, nf_ip_pri_nat_src = 100, nf_ip_pri_last = _max, };



hook是提供处理也就是我们主要工作其原型为:
unsigned nf_hookfn(unsigned hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, (*okfn)(struct sk_buff *));



5个参数将由nfhook宏传进去nf_register_hook根据reg中注册协议簇类型和优先级在nf_hooks中找到相应位置并插入到此表中_hooks[nproto][nf_max_hooks]在netfilter化时(netfilter_init/netfilter.c,而它在sock_init时)已经个空表 例如iptable在化时(init/iptable_filter.c)nf_register_hook注册他hook
struct nf_hook_ops ipt_ops = { { { null, null }, ipt_hook, pf_inet, nf_ip_local_in, nf_ip_pri_filter }, { { null, null }, ipt_hook, pf_inet, nf_ip_forward, nf_ip_pri_filter }, { { null, null }, ipt_local_out_hook, pf_inet, nf_ip_local_out, nf_ip_pri_filter } }; mangle在init/iptable_mangle.c中注册它自己hook struct nf_hook_ops ipt_ops = { { { null, null }, ipt_hook, pf_inet, nf_ip_pre_routing, nf_ip_pri_mangle }, { { null, null }, ipt_local_out_hook, pf_inet, nf_ip_local_out, {nf_ip_pri_mangle } };



nat在init/ip_nat_standalone.c中注册它自己hook /*包过滤前更改目地址*/   struct nf_hook_ops ip_nat_in_ops

Tags: 

延伸阅读

最新评论

发表评论