From 5eeff9bc0d0abc3f142ad2488a9106794dcd5bc7 Mon Sep 17 00:00:00 2001 From: Vadim Vetrov Date: Sun, 1 Sep 2024 20:58:50 +0300 Subject: [PATCH] Use netfilter hook instead of iptables target KISS principle is in action. No need to specify rules, just insmod youtubeUnblock and it works! --- Kbuild | 4 +- ipt_YTUNBLOCK.h | 6 -- kmake.mk | 29 ++------ iptk_YTUNBLOCK.c => kytunblock.c | 111 +++++++++++++++++++------------ libip6t_YTUNBLOCK.c | 26 -------- libipt_YTUNBLOCK.c | 26 -------- 6 files changed, 74 insertions(+), 128 deletions(-) delete mode 100644 ipt_YTUNBLOCK.h rename iptk_YTUNBLOCK.c => kytunblock.c (62%) delete mode 100644 libip6t_YTUNBLOCK.c delete mode 100644 libipt_YTUNBLOCK.c diff --git a/Kbuild b/Kbuild index 6501558..160e2eb 100644 --- a/Kbuild +++ b/Kbuild @@ -1,3 +1,3 @@ -obj-m := ipt_YTUNBLOCK.o -ipt_YTUNBLOCK-objs := iptk_YTUNBLOCK.o mangle.o quic.o utils.o kmod_utils.o +obj-m := kyoutubeUnblock.o +kyoutubeUnblock-objs := kytunblock.o mangle.o quic.o utils.o kmod_utils.o ccflags-y := -std=gnu11 -Wno-unused-variable -DKERNEL_SPACE -DDEBUG diff --git a/ipt_YTUNBLOCK.h b/ipt_YTUNBLOCK.h deleted file mode 100644 index 9394f39..0000000 --- a/ipt_YTUNBLOCK.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef IPT_YTUNBLOCK_H -#define IPT_YTUNBLOCK_H - -struct xt_ytunblock_tginfo {}; - -#endif /* IPT_YTUNBLOCK_H */ diff --git a/kmake.mk b/kmake.mk index 8520c51..9e7bbdf 100644 --- a/kmake.mk +++ b/kmake.mk @@ -10,41 +10,20 @@ LDFLAGS := IPT_CFLAGS := -Wall -Wpedantic -O2 .PHONY: kmake kload kunload kreload kclean kmclean xclean -kmake: kmod xmod +kmake: kmod kmod: $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules -xmod: libipt_YTUNBLOCK.so libip6t_YTUNBLOCK.so - -libipt_YTUNBLOCK.so: libipt_YTUNBLOCK.o - $(CCLD) -shared -fPIC ${IPT_CFLAGS} -o $@ $^; - -libipt_YTUNBLOCK.o: libipt_YTUNBLOCK.c - $(CC) ${IPT_CFLAGS} -D_INIT=lib$*_init -fPIC -c -o $@ $<; - -libip6t_YTUNBLOCK.so: libip6t_YTUNBLOCK.o - $(CCLD) -shared -fPIC ${IPT_CFLAGS} -o $@ $^; - -libip6t_YTUNBLOCK.o: libip6t_YTUNBLOCK.c - $(CC) ${IPT_CFLAGS} -D_INIT=lib$*_init -fPIC -c -o $@ $<; - kload: - insmod ipt_YTUNBLOCK.ko - cp ./libipt_YTUNBLOCK.so /usr/lib/xtables/ - cp ./libip6t_YTUNBLOCK.so /usr/lib/xtables/ + insmod kyoutubeUnblock.ko kunload: - -rmmod ipt_YTUNBLOCK - -/bin/rm /usr/lib/xtables/libipt_YTUNBLOCK.so - -/bin/rm /usr/lib/xtables/libip6t_YTUNBLOCK.so + -rmmod kyoutubeUnblock kreload: kunload kload -kclean: xtclean kmclean +kclean: kmclean kmclean: -$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean - -xtclean: - -/bin/rm -f libipt_YTUNBLOCK.so libipt_YTUNBLOCK.o diff --git a/iptk_YTUNBLOCK.c b/kytunblock.c similarity index 62% rename from iptk_YTUNBLOCK.c rename to kytunblock.c index f94c2b8..607aaf7 100644 --- a/iptk_YTUNBLOCK.c +++ b/kytunblock.c @@ -9,8 +9,11 @@ #include #include #include -#include -#include "ipt_YTUNBLOCK.h" +#include + +#include +#include +#include #include "mangle.h" #include "config.h" @@ -69,20 +72,23 @@ MODULE_VERSION("0.3.2"); MODULE_AUTHOR("Vadim Vetrov "); MODULE_DESCRIPTION("Linux kernel module for youtube unblock"); -static unsigned int ykb_tg(struct sk_buff *skb, const struct xt_action_param *par) -{ + +static unsigned int ykb_nf_hook(void *priv, + struct sk_buff *skb, + const struct nf_hook_state *state) { if ((skb->mark & config.mark) == config.mark) - return XT_CONTINUE; + goto accept_no_free; - if (skb->head == NULL) return XT_CONTINUE; + if (skb->head == NULL) + goto accept_no_free; uint32_t buflen = skb->len; if (buflen > MAX_PACKET_SIZE) - goto accept; + goto accept_no_free; NETBUF_ALLOC(buf, buflen); if (!NETBUF_CHECK(buf)) - goto no_free; + goto accept_no_free; if (skb_copy_bits(skb, 0, buf, buflen) < 0) { pr_err("Unable copy bits\n"); @@ -100,39 +106,27 @@ static unsigned int ykb_tg(struct sk_buff *skb, const struct xt_action_param *pa accept: NETBUF_FREE(buf); -no_free: - return XT_CONTINUE; +accept_no_free: + return NF_ACCEPT; drop: NETBUF_FREE(buf); kfree_skb(skb); return NF_STOLEN; } -static int ykb_chk(const struct xt_tgchk_param *par) { - return 0; -} - -static struct xt_target ykb_tg_reg __read_mostly = { - .name = "YTUNBLOCK", - .target = ykb_tg, - .table = "mangle", - .hooks = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD), - .targetsize = sizeof(struct xt_ytunblock_tginfo), - .family = NFPROTO_IPV4, - .checkentry = ykb_chk, - .me = THIS_MODULE, +static struct nf_hook_ops ykb_nf_reg __read_mostly = { + .hook = ykb_nf_hook, + .pf = NFPROTO_IPV4, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP_PRI_MANGLE, }; -static struct xt_target ykb6_tg_reg __read_mostly = { - .name = "YTUNBLOCK", - .target = ykb_tg, - .table = "mangle", - .hooks = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD), - .targetsize = sizeof(struct xt_ytunblock_tginfo), - .family = NFPROTO_IPV6, - .checkentry = ykb_chk, - .me = THIS_MODULE, +static struct nf_hook_ops ykb6_nf_reg __read_mostly = { + .hook = ykb_nf_hook, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP6_PRI_MANGLE, }; static int __init ykb_init(void) { @@ -141,24 +135,39 @@ static int __init ykb_init(void) { ret = open_raw_socket(); if (ret < 0) goto err; + if (config.use_ipv6) { ret = open_raw6_socket(); if (ret < 0) goto close_rawsocket; - ret = xt_register_target(&ykb6_tg_reg); - if (ret < 0) goto close_raw6socket; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) + struct net *n; + for_each_net(n) { + ret = nf_register_net_hook(n, &ykb6_nf_reg); + if (ret < 0) + lgerror("bad rat",ret); + } +#else + nf_register_hook(&ykb6_nf_reg); +#endif } - ret = xt_register_target(&ykb_tg_reg); - if (ret < 0) goto close_xt6_target; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) + struct net *n; + + for_each_net(n) { + ret = nf_register_net_hook(n, &ykb_nf_reg); + if (ret < 0) + lgerror("bad rat",ret); + } +#else + nf_register_hook(&ykb_nf_reg); +#endif pr_info("youtubeUnblock kernel module started.\n"); return 0; -close_xt6_target: - if (config.use_ipv6) xt_unregister_target(&ykb6_tg_reg); -close_raw6socket: - if (config.use_ipv6) close_raw6_socket(); close_rawsocket: close_raw_socket(); err: @@ -166,9 +175,25 @@ err: } static void __exit ykb_destroy(void) { - xt_unregister_target(&ykb_tg_reg); - if (config.use_ipv6) xt_unregister_target(&ykb6_tg_reg); - if (config.use_ipv6) close_raw6_socket(); + if (config.use_ipv6) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) + struct net *n; + for_each_net(n) + nf_unregister_net_hook(n, &ykb6_nf_reg); +#else + nf_unregister_hook(&ykb6_nf_reg); +#endif + close_raw6_socket(); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) + struct net *n; + for_each_net(n) + nf_unregister_net_hook(n, &ykb_nf_reg); +#else + nf_unregister_hook(&ykb_nf_reg); +#endif + close_raw_socket(); pr_info("youtubeUnblock kernel module destroyed.\n"); } diff --git a/libip6t_YTUNBLOCK.c b/libip6t_YTUNBLOCK.c deleted file mode 100644 index f7d4d1d..0000000 --- a/libip6t_YTUNBLOCK.c +++ /dev/null @@ -1,26 +0,0 @@ -// Used to register target in iptables -#include -#include - -#include -#include "ipt_YTUNBLOCK.h" - -#define _init __attribute__((constructor)) _INIT -#define __maybe_unused __attribute__((__unused__)) - -static void YTKB_help(void) { - printf("Youtube Unblock - bypass youtube slowdown DPI in Russia\n"); -} - -static struct xtables_target ykb6_tg_reg = { - .name = "YTUNBLOCK", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV6, - .size = XT_ALIGN(sizeof(struct xt_ytunblock_tginfo)), - .userspacesize = XT_ALIGN(sizeof(struct xt_ytunblock_tginfo)), - .help = YTKB_help, -}; - -void _init(void) { - xtables_register_target(&ykb6_tg_reg); -} diff --git a/libipt_YTUNBLOCK.c b/libipt_YTUNBLOCK.c deleted file mode 100644 index 5b7b099..0000000 --- a/libipt_YTUNBLOCK.c +++ /dev/null @@ -1,26 +0,0 @@ -// Used to register target in iptables -#include -#include - -#include -#include "ipt_YTUNBLOCK.h" - -#define _init __attribute__((constructor)) _INIT -#define __maybe_unused __attribute__((__unused__)) - -static void YTKB_help(void) { - printf("Youtube Unblock - bypass youtube slowdown DPI in Russia\n"); -} - -static struct xtables_target ykb_tg_reg = { - .name = "YTUNBLOCK", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct xt_ytunblock_tginfo)), - .userspacesize = XT_ALIGN(sizeof(struct xt_ytunblock_tginfo)), - .help = YTKB_help, -}; - -void _init(void) { - xtables_register_target(&ykb_tg_reg); -}