Модуль ядра для фильтрации запросов NFS - PullRequest
0 голосов
/ 11 марта 2020

Я работаю над проверочным модулем ядра для фильтрации запросов NFS на основе некоторых критериев (IP-адрес клиента, тип выполняемой операции и т. Д. c.) Я использовал хакерский метод, описанный в этот вопрос , но я не смог получить IP-адрес клиента в этом методе.

В настоящее время я думаю о том, чтобы иметь перехватчик Netfilter для перехвата сетевых пакетов, анализировать их, чтобы идентифицировать операции и применить фильтрацию там.

Он пример того, о чем я говорю .. Это для версии ядра 4.15.0

#include <linux/kernel.h>       /* We're doing kernel work */
#include <linux/module.h>       /* Specifically, a module, */
#include <linux/moduleparam.h>  /* which will have params */
#include <linux/unistd.h>       /* The list of system calls */
#include <linux/dirent.h>
#include <linux/cred.h>
#include <linux/syscalls.h>
#include <linux/init.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <linux/tcp.h>

static struct nf_hook_ops nfin;

static unsigned int hook_func_in(void *priv,
                   struct sk_buff *skb,
                   const struct nf_hook_state *state)
{
    struct ethhdr *eth;
    struct iphdr *ip_header;
    struct tcphdr *tcph;
    char *data;

    eth = eth_hdr(skb);
    ip_header = ip_hdr(skb);
    tcph = tcp_hdr(skb);
    data = (char *)((unsigned char *)tcph + (tcph->doff * 4));
    /* Skip if it's not TCP packet */
    if (ip_header->protocol != IPPROTO_TCP)
        return NF_ACCEPT;
    printk("src mac %pM --- src IP addr:%pI4 --- protocol: %u\n", eth->h_source, &ip_header->saddr, ip_header->protocol);
    printk("TCP source : %hu, TCP  dest : %hu\n", ntohs(tcph->source), ntohs(tcph->dest));
    // Parse data pointer here..
    return NF_ACCEPT;
}

int init_module()
{
    nfin.hook     = hook_func_in;
    nfin.hooknum  = NF_INET_LOCAL_IN;
    nfin.pf       = PF_INET;
    nfin.priority = 0;
    nf_register_net_hook(&init_net, &nfin);
    return 0;
}

void cleanup_module()
{
    nf_unregister_net_hook(&init_net, &nfin);
}

Как я могу разобрать указатель данных, чтобы иметь возможность определить тип запроса, который я обрабатываю? или как разобрать запрос RP C от объекта sk_buff?

Это правильный подход к go относительно этой задачи?

...