加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Netfilter NF_HOOK执行流程分析一

(2012-11-08 17:47:22)
标签:

it

分类: network

    利用Linux 我们可以实现复杂的防火墙机制,大家防火墙路由器,得易于Linux 强大的内核,这些实现都变得非常简单,通过简单的几条iptables命令就可以定制我们的防火墙功能。那么Linux内核是如何完成对包的处理,流程又是怎么样呢?

一 首先看一下netfilter的整体架构

http://s14/middle/694f2ae74cdf8b87345dd&690NF_HOOK执行流程分析一" />

netfilter的具体实现,以NF_IP_PREROUTING为例

二 NF_HOOK的实现原理

    在网卡收到包之后交由ip层处理的时候,就交给了ip_recv函数

int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)

{

    在做了基本的头校验等工作后,就到了我们的重点NF_HOOK钩子函数,此时还未作路由等路处理

    return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL,

         ip_rcv_finish);

    在做完PRE_ROUTING的筛选后,会执行ip_recv_finish函数,继续执行路由等处理,如果是本地的就会交给更高层的协议进行处理,如果不是交由本地的就执行FORWARD

}

通过NF_HOOK的宏定义可以看到,NF_HOOK主要是调用nf_hook_slow,那么,nf_hook_slow主要做了哪些东西呢?

nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh)

{

    elem = &nf_hooks[pf][hook];

next_hook:

    verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev,

             outdev, &elem, okfn, hook_thresh);

}

nf_interate 的作用就是递归调用注册的钩子函数,

unsigned int nf_iterate(struct list_head *head,struct sk_buff *skb,unsigned int hook,const struct net_device *indev,

            const struct net_device *outdev,struct list_head **i,int (*okfn)(struct sk_buff *),int hook_thresh)

{

    list_for_each_continue_rcu(*i, head) {

        struct nf_hook_ops *elem = (struct nf_hook_ops *)*i;

        if (hook_thresh > elem->priority)

            continue;   

repeat:

        verdict = elem->hook(hook, skb, indev, outdev, okfn);

        if (verdict != NF_ACCEPT) {

#ifdef CONFIG_NETFILTER_DEBUG

            if (unlikely((verdict & NF_VERDICT_MASK)

                            > NF_MAX_VERDICT)) {

                NFDEBUG("Evil return from %p(%u).\n",

                    elem->hook, hook);

                continue;

            }

#endif

            if (verdict != NF_REPEAT)

                return verdict;

            goto repeat;

        }

    }

    return NF_ACCEPT;

}

三 filter NAT mangle链的具体实现

    我们知道,iptables默认的可以配置三个表,分别是FILTER, NAT, MANGLE,那么这三个表是如何跟NF_HOOK联系的呢?

先看一下下面的结构体

struct nf_hook_ops {

    struct list_head list;

    nf_hookfn *hook;

    struct module *owner;

    u_int8_t pf;

    unsigned int hooknum;

    int priority;

};

其实nf_iterate就是递归搜索list 执行hook函数。

使用# iptables –nvL,可以看到有如下的输出,这三个表是怎么注册上去的呢?

http://s9/middle/694f2ae74cdf8b87e4df8&690NF_HOOK执行流程分析一" />

http://s11/middle/694f2ae74cdf8b87cbf3a&690NF_HOOK执行流程分析一" />

static int __init iptable_filter_init(void)

{

    filter_ops = xt_hook_link(&packet_filter, iptable_filter_hook);

    if (IS_ERR(filter_ops)) {

        ret = PTR_ERR(filter_ops);

        goto cleanup_table;

}

http://s12/middle/694f2ae74cdf8b88b3bfb&690NF_HOOK执行流程分析一" />

防火墙分别在(1 << NF_INET_LOCAL_IN) | \ (1 << NF_INET_FORWARD) | \ (1 << NF_INET_LOCAL_OUT))注册HOOK函数,并执行iptable_filter_hook函数。

http://s9/middle/694f2ae7300bb735c2fe8&amp;690NF_HOOK执行流程分析一" />

到了这里大体就明白了,NF_HOOK执行相应额HOOK函数,例如在IP_PREROUTING里面执行防火墙注册的HOOK函数,也就是到了iptables_filter_hook,然后遍历FILTER里面的各个table,执行相应的动作。那么table是怎么跟一条规则相对应的呢,那得先看一下ipt_do_table是怎么实现的。我把ipt_do_table执行的大体流程粘帖如下

http://s14/middle/694f2ae74cdf8b8a1312d&amp;690NF_HOOK执行流程分析一" />

http://s15/middle/694f2ae707aff45a8692e&amp;690NF_HOOK执行流程分析一" />

ipt_do_table 就是遍历entry匹配IP五元组,然后执行相应的target动作,如下图所示:

http://s9/middle/694f2ae74cdf8b89cd9e8&amp;690NF_HOOK执行流程分析一" />

举例:

如果执行如下的命令,在执行上述的步骤后,匹配好无元组之后,会跳转到REJECT target

iptables -A PREROUTING -s 10.10.10.1 -j REJECT

http://s8/middle/694f2ae74cdf8b8afcb77&amp;690NF_HOOK执行流程分析一" />

然后调用reject_ta_reg,采取必要的步骤后,将包丢掉。

 

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有