Netfilter 简易分析

Netfilter作为第三方源码拥有自己的网站http://www.netfilter.org/,确实比较牛逼。
尤其是应用层iptables作为工具对构建linux防火墙进行发挥特别大的作用。
Linux下通过nf_register_hooks对钩子函数进行注册,通过source insight对源码进行查看,
发现这么多地方调用了函数。
/* Connection tracking may drop packets, but never alters them, so
   make it the first hook. */
static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
    {
        .hook       = ipv4_conntrack_in,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_PRE_ROUTING,
        .priority   = NF_IP_PRI_CONNTRACK,
    },
    {
        .hook       = ipv4_conntrack_local,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_LOCAL_OUT,
        .priority   = NF_IP_PRI_CONNTRACK,
    },
    {
        .hook       = ipv4_confirm,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_POST_ROUTING,
        .priority   = NF_IP_PRI_CONNTRACK_CONFIRM,
    },
    {
        .hook       = ipv4_confirm,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_LOCAL_IN,
        .priority   = NF_IP_PRI_CONNTRACK_CONFIRM,
    },
};

static struct nf_hook_ops ipv4_defrag_ops[] = {
    {
        .hook       = ipv4_conntrack_defrag,
        .owner      = THIS_MODULE,
        .pf     = PF_INET,
        .hooknum    = NF_INET_PRE_ROUTING,
        .priority   = NF_IP_PRI_CONNTRACK_DEFRAG,
    },
    {
        .hook           = ipv4_conntrack_defrag,
        .owner          = THIS_MODULE,
        .pf             = PF_INET,
        .hooknum        = NF_INET_LOCAL_OUT,
        .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
    },
};

/* We must be after connection tracking and before packet filtering. */

static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
    /* Before packet filtering, change destination */
    {
        .hook       = nf_nat_in,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_PRE_ROUTING,
        .priority   = NF_IP_PRI_NAT_DST,
    },
    /* After packet filtering, change source */
    {
        .hook       = nf_nat_out,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_POST_ROUTING,
        .priority   = NF_IP_PRI_NAT_SRC,
    },
    /* Before packet filtering, change destination */
    {
        .hook       = nf_nat_local_fn,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_LOCAL_OUT,
        .priority   = NF_IP_PRI_NAT_DST,
    },
    /* After packet filtering, change source */
    {
        .hook       = nf_nat_fn,
        .owner      = THIS_MODULE,
        .pf     = NFPROTO_IPV4,
        .hooknum    = NF_INET_LOCAL_IN,
        .priority   = NF_IP_PRI_NAT_SRC,
    },
};

#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
                (1 << NF_INET_FORWARD) | \
                (1 << NF_INET_LOCAL_OUT))

static const struct xt_table packet_filter = {
    .name       = "filter",
    .valid_hooks    = FILTER_VALID_HOOKS,
    .me     = THIS_MODULE,
    .af     = NFPROTO_IPV4,
    .priority   = NF_IP_PRI_FILTER,
};

#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
                (1 << NF_INET_LOCAL_IN) | \
                (1 << NF_INET_FORWARD) | \
                (1 << NF_INET_LOCAL_OUT) | \
                (1 << NF_INET_POST_ROUTING))

static const struct xt_table packet_mangler = {
    .name       = "mangle",
    .valid_hooks    = MANGLE_VALID_HOOKS,
    .me     = THIS_MODULE,
    .af     = NFPROTO_IPV4,
    .priority   = NF_IP_PRI_MANGLE,
};

#define NAT_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
             (1 << NF_INET_POST_ROUTING) | \
             (1 << NF_INET_LOCAL_OUT) | \
             (1 << NF_INET_LOCAL_IN))

static const struct xt_table nat_table = {
    .name       = "nat",
    .valid_hooks    = NAT_VALID_HOOKS,
    .me     = THIS_MODULE,
    .af     = NFPROTO_IPV4,
};
其中filter,mangle 表通过xt_hook_link间接调用了 nf_register_hook, 
分别注册了回调 iptable_filter_hook和iptable_mangle_hook 。  
倒是nat表没有像 filter,mangle采用这种方式,而是
nf_nat_ops 这些回调函数与nat表产生了千丝万缕的关系。
通过一番priority的比较,最终总结出了各个钩子函数的调戏skb的关系图,

PRE_ROUTING                                                                                                     
    ipv4_conntrack_defrag(NF_IP_PRI_CONNTRACK_DEFRAG)
    ipv4_conntrack_in(NF_IP_PRI_CONNTRACK)
    iptable_mangle_hook(NF_IP_PRI_MANGLE)
    nf_nat_in(NF_IP_PRI_NAT_DST)

FORWARD
    iptable_mangle_hook(NF_IP_PRI_MANGLE)
    iptable_filter_hook(NF_IP_PRI_FILTER)

LOCAL_IN                                                            
    iptable_mangle_hook(NF_IP_PRI_MANGLE)
    ipv4_conntrack_defrag(NF_IP_PRI_CONNTRACK_DEFRAG)
    nf_nat_fn(NF_IP_PRI_NAT_SRC)
    iptable_filter_hook(NF_IP_PRI_FILTER)
    ipv4_confirm(NF_IP_PRI_CONNTRACK_CONFIRM)

 LOCAL_OUT
     ipv4_conntrack_local(NF_IP_PRI_CONNTRACK)
     iptable_mangle_hook(NF_IP_PRI_MANGLE)   
     nf_nat_local_fn(NF_IP_PRI_NAT_DST)
     iptable_filter_hook(NF_IP_PRI_FILTER)

 POST_ROUTING
     iptable_mangle_hook(NF_IP_PRI_MANGLE)
     nf_nat_out(NF_IP_PRI_NAT_SRC)
     ipv4_confirm(NF_IP_PRI_CONNTRACK_CONFIRM)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值