Frage

Grundsätzlich möchte ich ein Kernel -Modul schreiben, das EBTables einen möglichen Filter hinzufügt. Dann muss ich Ebtables sagen, dass sie meinen Filter auf einer Brücke verwenden sollen, die ich eingerichtet habe.

Der Grund, warum ich mein eigenes Modul schreiben muss, ist, dass ich eine Verzögerung zwischen aufeinanderfolgenden Paketen einführen möchte (aus irgendeinem Testgründen). Um zu demonstrieren, hat mein Netzwerk ursprünglich einen Verkehr wie diesen:

+++-----------------+++-----------------+++-----------------+++-----------------

wo + zeigt den Verkehr eines Pakets und - bedeutet kein Paket in der Leitung. Ich möchte eine Brücke dazwischen stellen, damit sich das Muster der Pakete zu diesem Zeitpunkt ändern würde:

+----+----+---------+----+----+---------+----+----+---------+----+----+---------

Dies bedeutet, dass ich sicherstellen würde, dass zwischen der Ankunft jedes Pakets eine gewisse Verzögerung besteht.

Jetzt habe ich den folgenden einfachen Code geschrieben, den ich grundsätzlich von Linux-Source/net/bridge/netfilter/ebt_ip.c genommen habe:

static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
    printk(KERN_INFO"match called\n");
    return true;  // match everything!
}

static bool check(const struct xt_mtchk_param *par)
{
    printk(KERN_INFO"check called\n");
    return true;  // pass everything!
}

static struct xt_match reg __read_mostly = {
    .name = "any",   // I made this up, but I tried also putting ip for example which didn't change anything.
    .revision = 0,
    .family = NFPROTO_BRIDGE,
    .match = match,
    .checkentry = check,
    .matchsize = XT_ALIGN(4),  // don't know what this is, so I just gave it an `int`
    .me = THIS_MODULE
};

int init_module(void)
{
    return xt_register_match(&reg);
}

void cleanup_module(void)
{
    xt_unregister_match(&reg);
}

Ich lade das Modul erfolgreich. Aber es ist, als wäre es nicht da. Ich bekomme die Protokolle nicht hinein match und check Funktionen, sodass die Brücke meinen Filter eindeutig nicht berücksichtigt. Was mache ich falsch?

Ich habe viele Kombinationen zum Laden meines Filters zuerst ausprobiert, zuerst die Brücke eingerichtet oder zuerst EBTables -Regeln festgelegt, aber keiner von ihnen ändert etwas.

PS Die Brücke selbst funktioniert. Ich bin sicher, dass EBTables auch in Kraft sind, denn wenn ich eine Richtlinie zum Absetzen von Paketen hinzufüge, erhalte ich sie nicht auf dem letzten Computer. Was ich nicht herausfinden kann, ist, wie ich Ebtables auch über meinen Filter in Betracht ziehen soll.

War es hilfreich?

Lösung

Um ein Kernel -Modul zu verwenden, müssen Sie auch ein geeignetes Plugin für das UserSpace -Programm schreiben und danach eine Regel einfügen, in der es aufgerufen wird.

Wenn Sie keine Optionen haben, geben Sie keine an .matchsize Parameter in struct xt_match (Gleiche an die Angabe von 0).

Andere Tipps

Ich habe das funktioniert, nicht auf die eleganteste Weise, aber ich schreibe es hier für einen zukünftigen Wanderer:

Nehmen wir an, Ihr Filtername lautet: "Any"

User-Space-Plugin

Sie benötigen Header, die außerhalb der EBTables -Quelle nicht verfügbar sind. Holen Sie sich also den Quellcode und gehen Sie in den Ordner "Erweiterungen". In der Makefile hinzufügen any zu EXT_FUNC (Das sind Ziele zu erstellen) und schreiben die Quelldatei ebt_any.c wie die folgende:

#include <stdio.h>
#include <getopt.h>
#include "../include/ebtables_u.h"

/*struct whatever
{
        int a;
};*/

static struct option _any_opts[] =
{
        {"use-any", required_argument, 0, 0},
        {'\0'}
};

static void _any_help(void)
{
        printf("any match options: nothing!\n");
}

static void _any_init(struct ebt_entry_match *match)
{
        printf("any_init\n");
}

static void _any_check(const struct ebt_u_entry *entry, const struct ebt_entry_match *match, const char *name,
        unsigned int hookmask, unsigned int time)
{
        printf("any_check\n");
}

static int _any_parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_match **match)
{
        printf("any_parse: %d\n", c);
        if (c == 0)
                return 1;
        return 0;       // return true for anything
}

static int _any_compare(const struct ebt_entry_match *m1, const struct ebt_entry_match *m2)
{
/*      struct whatever *w1 = (struct whatever *)m1->data;
        struct whatever *w2 = (struct whatever *)m2->data;
        if (w1->a != w2->a)
                return 0;*/
        return 1;
}

static void _any_print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
{       
        printf("any_print");
}

static struct ebt_u_match _reg = {
        .name           = "any",
//      .size           = sizeof(struct whatever),
        .help           = _any_help,
        .init           = _any_init,
        .parse          = _any_parse,
        .final_check    = _any_check,
        .print          = _any_print,
        .compare        = _any_compare,
        .extra_ops      = _any_opts,
};

void _init(void)
{
        ebt_register_match(&_reg);
}

Notiz: Wenn Sie Daten haben, die vom Benutzerraum zum Kernel-Raum wechseln, schreiben Sie etwas anstelle von struct whatever. Ich habe es kommentiert, weil ich nichts benutze.

Notiz: Auch wenn Ihr Programm keine Option erfordert (z. B. meine, die mit allem übereinstimmen sollte), müssen Sie trotzdem eine Option geben, da EBTables Ihren Filter verwenden kann.

Notiz: Einige dieser Funktionen scheinen unnötig zu sein, aber wenn Sie sie nicht schreiben, erhalten Sie einen Fehler "Bug: Bad Merge".

Kernel-Raum-Modul

Das Kernel-Raum-Modul ist einfacher:

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

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Shahbaz Youssefi");
MODULE_ALIAS("ebt_any");

/*struct whatever
{
        int a;
};*/

static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
        printk(KERN_INFO"Matching\n");
        return true;
}

static bool check(const struct xt_mtchk_param *par)
{
        printk(KERN_INFO"Checking\n");
        return true;
}

static struct xt_match reg __read_mostly = {
        .name           = "any",
        .match          = match,
//      .matchsize      = sizeof(struct whatever),
        .checkentry     = check,
        .me             = THIS_MODULE
};

int init_module(void)
{       
        int ret = 0;
        printk("Bridge initializing...\n");
        ret = xt_register_match(&reg);
        printk("Bridge initializing...done!\n");
        return ret;
}

void cleanup_module(void)
{
        printk("Bridge exiting...\n");
        xt_unregister_match(&reg);
        printk("Bridge exiting...done!\n");
}

Notiz: wenn du benutzt struct whatever Im Benutzerraum müssen Sie dasselbe im Kernel-Raum verwenden.

Notiz: Im Gegensatz zu User-Space-Plugin, bei dem EBTables Header/Funktionen verwendet werden, verwendet das Kernel-Modul stattdessen Xtables !!

Kompilieren Sie das Modul (ziemlich Standard) und installieren Sie es für die automatische Belastung. Alternativ können Sie insmod und rmmod Das Modul selbst vor dem Hinzufügen/Nach dem Entfernen von EBTables -Regeln.

So verwenden Sie eBTables Ihren Filter

Fügen Sie einfach eine Regel hinzu, die enthält --use-any some_value Und du bist gut. Zum Beispiel:

ebtables -A FORWARD --use-any 1 -j ACCEPT

Notiz: Dies --use-any ist der option das wurde in gegeben ebt_u_match reg.extra_ops (was in Array definiert wurde _any_opts) im Benutzerraum Plugin.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top