如何使用netfilter删除某些软件包在Linux上有一些规范数据?

时间:2015-12-06 15:54:02

标签: linux kernel netfilter

我搜索了很长时间,但只是可以获取IP并立即记录它们。

    __be32 sip,dip;
 if(skb){
   struct sk_buff *sb = NULL;
   sb = skb;
   struct iphdr *iph;
   iph  = ip_hdr(sb);
   sip = iph->saddr;
   dip = iph->daddr;
   printk("Packet for source address: %d.%d.%d.%d\n destination address: %d.%d.%d.%d\n ", NIPQUAD(sip), NIPQUAD(dip));
        }
 return NF_ACCEPT;

我尝试sb->data但无法获得类似于数据包的内容..

我只想删除包含这些数据的包data.data == 25:3f:08:52:45:47:49:53:54:45:52:46:4d:4c:00:46:4d:4c:7c:48:53:00:46:4f:52:47:45:00:42:75:6e:67:65:65:43:6f:72:64,因为这些包可能来自某个attcker ..

我应该使用netfilter(Linux kernel)吗?我无法更改程序的代码,因此我想通过Centos删除这些软件包。

1 个答案:

答案 0 :(得分:1)

这是一个简单的模块:

#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Reuven Plevinsky");

static struct nf_hook_ops nfho;

int search_str(struct sk_buff *skb, char* str, int len)
{
    int buf_len = skb->tail - skb->data;
    int  i, j, offset;
    if (len > buf_len)
        return -1;
    for (i = 0, j = 0, offset = 0; (i < buf_len && j < len);)
    {
        if (skb->data[i] == str[j])
        {
            if (j == 0)
                offset = i;
            if (j == len - 1)
                return offset;
            else
            {
                i++;
                j++;
            }
        }
        else
        {
            if (j != 0)
            {
                i = offset + 1;
                j = 0;
            }
            else
            {
                i++;
            }
        }
    }
    return -1;
}

unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
    __u32 src_add;
    __u32 dst_add;
    struct iphdr *ip_header;
    char* mal = "%?REGISTERFMLFML|HSFORGEBungeeCord";
    int len = 34, ret;
    ip_header = (struct iphdr *)skb_network_header(skb);    
    src_add = ip_header->saddr;
    dst_add = ip_header->daddr;
    ret = search_str(skb, mal, len);
    if (ret == -1)
    {
        printk(KERN_INFO "no match\n");
        return NF_ACCEPT;                                           
    }
    else
    {
        printk(KERN_INFO "match at offset %d\n", ret);
        return NF_DROP;
    }
}


int init_module()
{
    printk(KERN_DEBUG "init module\n");
    nfho.hook = hook_func;            
    nfho.hooknum = NF_INET_PRE_ROUTING;     
    nfho.pf = PF_INET;                        
    nfho.priority = NF_IP_PRI_FIRST;      
    nf_register_hook(&nfho);              
    return 0;                 
}

void cleanup_module()
{
    printk(KERN_DEBUG "cleanup module\n");
    nf_unregister_hook(&nfho);
} 

注意:大端的所有IP都是。如果要检查源IP,则必须使用ntohl转换它。

字符串并不完全是您要找的,但类似。