Я работаю над проверочным модулем ядра для фильтрации запросов 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 относительно этой задачи?