linux 커널

netfilter hook을 이용한 fw 만들기

駝鳥 2023. 12. 18. 21:24

안녕하세요

금일 포스팅 할 내용은 리눅스 커널 모듈을 이용해 netfilter hook을 사용하는 방법입니다.

 

netfilter란

커널의 네트워크 프레임워크 중 하나로  hook을 제공하여 원하는 패킷을 drop할 수 있다.

 

netfilter hook등록

netfilter는 hook을 등록하고 등록해제하는 함수가 있다.

nf_register_hook 을 이용해 설정한 nf_hook_ops 구조체를 넘겨주면 등록이 됩니다.

 

해당 함수를 이용하여 함수를 등록하고 해제를 한다.

netfilter hook의 예시입니다.

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

static struct nf_hook_ops my_nf_ops;

static unsigned int my_hook_function(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    if (skb)
    {
        printk(KERN_INFO "Received skb data length: %d\n", skb->len);
        if (skb->len > 0)
        {
            int i;
            printk(KERN_INFO "Received skb data: ");
            for (i = 0; i < skb->len; i++)
            {
                printk("%02x ", skb->data[i]);
            }
        }
    }
    return NF_ACCEPT;
}

static int __init my_init(void)
{
    printk(KERN_INFO "Hello, Kernel Module!\n");

    my_nf_ops.hook = my_hook_function;
    my_nf_ops.pf = PF_INET;
    my_nf_ops.hooknum = NF_INET_PRE_ROUTING;
    my_nf_ops.priority = NF_IP_PRI_FIRST;

    nf_register_net_hook(&init_net, &my_nf_ops);

    return 0;
}

static void __exit my_exit(void)
{
    printk(KERN_INFO "Goodbye, Kernel Module!\n");

    nf_unregister_net_hook(&init_net, &my_nf_ops);
}

module_init(my_init);
module_exit(my_exit);

 

callback 함수

callback함수에서는 소켓버퍼인 skb에 있는 데이터를 출력해볼것입니다.

static unsigned int my_hook_function (void *priv, struct sk_buff *skb, const struct nf_hook_state *state)

해당 함수에서는 들어오는 패킷을 printk로 데이터 하나하나씩 출력한다.

%s로 출력해 보았으나 제대로 출력되지 않아 데이터 한자한자씩 출력하게 해보았습니다.

 

 

감사합니다.