ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

OpenWrt内核模块开发(五)-通过linux netfilter框架实现ip地址过滤

2021-07-19 11:34:09  阅读:351  来源: 互联网

标签:src ip dst 192.168 8.8 66.167 OpenWrt 内核模块


文章目录

ip_filter

功能简介

通过内核模块的方式向netfilter框架注册钩子函数,分析ip头部信息,提取源ip和目的ip,匹配到指定ip地址后进行过滤。

网络层

网络层引入了IP协议,制定了一套新地址,使得我们能够区分两台主机是否同属一个网络,这套地址就是网络地址,也就是所谓的IP地址。IP协议将这个32位的地址分为两部分,前面部分代表网络地址,后面部分表示该主机在局域网中的地址。如果两个IP地址在同一个子网内,则网络地址一定相同。为了判断IP地址中的网络地址,IP协议还引入了子网掩码,IP地址和子网掩码通过按位与运算后就可以得到网络地址。

通俗点讲,网络层就是以ip地址为唯一标识进行数据转发的,ip地址可以唯一标识一台主机。因此我们如果过滤局域网的ip地址,可以达到限制某台设备上网的效果,而如果过滤公网的ip地址,就可以限制所有设备访问特定资源的效果。

netfilter注册钩子函数

这里我们将hooknum设置为NF_INET_FORWARD

static struct nf_hook_ops ip_filter_ops[] __read_mostly = {
    {
        .hook = ip_filter_hook,
        .pf = PF_INET,
        .hooknum = NF_INET_FORWARD,
        .priority = NF_IP_PRI_FIRST + 1,
    },
};

static int __init ip_filter_init(void)
{
    printk("ip filter...init\n");
    nf_register_net_hooks(&init_net, ip_filter_ops, ARRAY_SIZE(ip_filter_ops));
    return 0;
}

ip过滤钩子函数分析

源码

static u_int32_t ip_filter_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    struct nf_conn *ct = (struct nf_conn *)skb->_nfct;
    struct udphdr *udph = NULL;
    struct iphdr *iph = NULL;
    int i;
    char *black_ip_list[] = {
        "192.168.66.167",
        "8.8.8.8",
        "114.114.114.114",
        NULL
    };

    if (ct == NULL || !nf_ct_is_confirmed(ct))
    {
        return NF_ACCEPT;
    }

    iph = ip_hdr(skb);
    if (!iph)
        return NF_ACCEPT;
    char src_ip[32] = {0};
    char dst_ip[32] = {0};
    sprintf(src_ip, "%pI4", &iph->saddr);
    sprintf(dst_ip, "%pI4", &iph->daddr);
    printk("src_ip = %s, dst_ip = %s\n", src_ip, dst_ip);
    for (i = 0; black_ip_list[i] != NULL; i++)
    {
        if (0 == strcmp(src_ip, black_ip_list[i]) ||
            0 == strcmp(dst_ip, black_ip_list[i]))
        {
            printk("drop ippacket %pI4--->%pI4\n", &iph->saddr, &iph->daddr);
            return NF_DROP;
        }
    }

    return NF_ACCEPT;
}

分析
源码中提取了ip头部的源ip和目的ip,并查询我们配置的过滤ip列表,匹配成功将返回NF_DROP进行丢包处理。

编译运行

参考前面章节

测试结果

root@OpenWrt:/fros# 
root@OpenWrt:/fros# insmod ip_filter.ko 
root@OpenWrt:/fros# <4>[52786.030458] ip filter...init
<4>[52797.584631] src_ip = 192.168.66.167, dst_ip = 8.8.8.8
<4>[52797.589199] drop ippacket 192.168.66.167--->8.8.8.8
<4>[52798.585038] src_ip = 192.168.66.167, dst_ip = 8.8.8.8
<4>[52798.588543] drop ippacket 192.168.66.167--->8.8.8.8
<4>[52799.585729] src_ip = 192.168.66.167, dst_ip = 8.8.8.8
<4>[52799.588981] drop ippacket 192.168.66.167--->8.8.8.8
<4>[52800.586586] src_ip = 192.168.66.167, dst_ip = 8.8.8.8
<4>[52800.590504] drop ippacket 192.168.66.167--->8.8.8.8
<4>[52816.371851] src_ip = 192.168.66.167, dst_ip = 39.156.69.79
<4>[52816.376783] drop ippacket 192.168.66.167--->39.156.69.79
<4>[52817.373089] src_ip = 192.168.66.167, dst_ip = 39.156.69.79
<4>[52817.378449] drop ippacket 192.168.66.167--->39.156.69.79
<4>[52818.373501] src_ip = 192.168.66.167, dst_ip = 39.156.69.79
<4>[52818.379103] drop ippacket 192.168.66.167--->39.156.69.79
<4>[52819.374765] src_ip = 192.168.66.167, dst_ip = 39.156.69.79
<4>[52819.376784] drop ippacket 192.168.66.167--->39.156.69.79
<4>[52820.376567] src_ip = 192.168.66.167, dst_ip = 39.156.69.79
<4>[52820.380384] drop ippacket 192.168.66.167--->39.156.69.79

作者简介

OpenWrt应用过滤插件作者(应用过滤用于控制app联网,可以过滤游戏、视频、聊天等几百款app)
从事嵌入式Linux开发近10年,主要负责路由器网通产品研发,精通OpenWrt系统,包括luci、消息机制、内核模块等。擅长模块:路由器上网行为管理、智能流控、上网认证、防火墙、虚拟服务器、多wan负载均衡等

开源作品地址:
https://github.com/destan19/OpenAppFilter

源码和文档

关注微信公众号可以获取更多技术文档、固件、源码等
微信扫码关注:

标签:src,ip,dst,192.168,8.8,66.167,OpenWrt,内核模块
来源: https://blog.csdn.net/dxt1107/article/details/118891743

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有