代码框内引用的代码来自2.6内核
一.通用防火墙简介:
Linux上的防火墙一般是通过Netfilter来实现对包的有规则的过滤,防火墙模块在Linux上注册成为/dev的一个字符设备,通过 ioctl()设置过滤规则,在5个HOOK(ipv4中是5个)钓鱼点设置钩子函数,一般设置规则是通过设置相关的(源IP,源PORT,目的IP,目的IP)来实现。
二.Netfilter:
Netfilter是一个框架,可以实现包过滤,NAT(net addr trans 网络地址转换),网络连接跟踪等功能。
在IPV4中有5个HOOK点,我们称为钓鱼点,因为在这些地方,可以设置钩子函数(鱼钩)来获取符合条件的数据包(鱼)。5个HOOK点如下:
HOOK点 | 说 明 | 函数位置 | 应用举例 |
NF_IP_PRE_ROUTING | 由网卡传入主机的数据包,在没有经过IP层路由之前,会先经过这个点 | ip_rcv() | 过滤拒绝服务攻击\NAT\计算 |
NF_IP_LOCAL_IN | 经过路由选择,要进入本机的数据包,会经过这个点 |
ip_local_deliver() 在此处可进行碎片重组 |
防火墙过滤进入本机的包 |
NF_IP_FORWARD | 经过路由,不是发往本机的包,需要向外发送,会经过这个点 | ip_forward() 之后进入ip_send() |
|
NF_IP_LOCAL_OUT | 本机发往外部的数据包在经过路由之前会经过这个点 | ip_build_and_send_pkt() ip_queue_xmit() ip_build_xmit_slow() ip_buid_xmit() 不同的上层协议会走不同的流程 |
防火墙过滤外发的数据包 |
NF_IP_POST_ROUTING 所有外出包都必须经过的钩子点 |
本机发送出去的包,在路由后会经过此点 | ip_finish_output() | 包计数功能实现 |
数据流描述:
简单的校验
|
NF_IP_PRE_ROUTING->
|
路由
|
发往本机—>发往外部 ->NF_IP_FORWARD—->NF_IP_POST_ROUTING
|
NF_IP_LOCAL_IN
|
高层的协议及进程
|
发包
|
NF_IP_LOCAL_OUT
|
路由
|
NF_IP_POST_ROUTING
HOOK函数的返回值
#define 0 |
nf_hook_ops数据结构:
include/linux/netfilter.h
//其中hookfn声明如下: typedef unsigned int (unsigned int ,//具体的hook类型 struct *,//socket缓冲区 const struct *, //输入设备(收到包的设备net_device指针) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //外发的包为NULL const struct *,//接口(数据包离开所需要的net_device指针) int (*)(struct *));//okfn,所有注册的hook函数都返回NF_ACCEPT时,调用
< /td> |
三。 NF_HOOK宏
调用该宏将筛选过滤功能的代码连接到NETFILTER 中
四。注册Netfilter HOOK函数
(就是向链表中添加一个节点,属性由协议簇和hook类型来确定)
首先初始化一个 nf_hook_ips节点(见上方的解析)
struct list_head nf_hooks[NPROTO指定协议族][NF_MAX_HOOKS指定hook类型]
内核中使用示例
|