4

基本的には、ebtables に可能なフィルターを追加するカーネル モジュールを作成したいと考えています。次に、設定したブリッジでフィルターを使用するように ebtables に指示する必要があります。

独自のモジュールを作成する必要があるのは、連続するパッケージ間に遅延を導入したいからです (何らかのテスト上の理由から)。実証するために、私のネットワークにはもともと次のようなトラフィックがあります。

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

ここで+、 はパッケージのトラフィックを示し-、ライン上にパッケージがないことを意味します。パケットのパターンが次のように変わるように、間にブリッジを配置したいと思います。

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

これは、各パケットの到着の間に一定量の遅延があることを確認することを意味します。

これで、基本的に linux-source/net/bridge/netfilter/ebt_ip.c から取得した次の簡単なコードを作成しました。

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);
}

モジュールのロードに成功しました。しかし、それはあたかもそこにないかのようです。内部のログmatchcheck機能を取得していないため、ブリッジは明らかにフィルターを考慮していません。私は何を間違っていますか?

最初にフィルターをロードする、最初にブリッジをセットアップする、または最初に ebtables ルールを設定するという多くの組み合わせを試しましたが、どれも何も変わりません。

PSブリッジ自体は機能します。パッケージをドロップするポリシーを追加すると、最終的なコンピューターでそれらを受信しないため、ebtables も有効であると確信しています。私が理解できないのは、私のフィルターも考慮するようにebtablesに指示する方法です。

4

2 に答える 2

7

私はこれを最もエレガントな方法ではなく機能させましたが、とにかく、将来の放浪者のためにここに書いています:

フィルタ名が「any」であるとしましょう

ユーザースペースプラグイン

ebtablesソースの外部では利用できないヘッダーが必要です。したがって、ソースコードを取得し、拡張機能フォルダーに移動します。Makefileで、に追加anyEXT_FUNC(つまり、ビルドするターゲット)ebt_any.c、次のようにソースファイルを書き込みます。

#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);
}

注:ユーザースペースからカーネルスペースに移動するデータがある場合は、の代わりに何かを記述してstruct whateverください。何も使っていないのでコメントアウトしました。

注:プログラムにオプション(すべてに一致するはずの私のものなど)が必要ない場合でも、ebtablesがフィルターの使用を知っているので、とにかくオプションを指定する必要があります。

注:これらの関数の一部は不要に見えますが、これらを記述しないと、「BUG:不正なマージ」エラーが発生します。

カーネル空間モジュール

カーネル空間モジュールはより単純です:

#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");
}

注:ユーザースペースで使用する場合struct whateverは、カーネルスペースでも同じものを使用する必要があります。

注: ebtablesヘッダー/関数を使用するユーザースペースプラグインとは異なり、カーネルモジュールは代わりにxtablesを使用します!!

モジュール(かなり標準)をコンパイルし、自動ロード用にインストールします。または、 ebtablesルールを追加/削除する前に、モジュールを自分で作成するinsmodこともできます。rmmod

ebtablesにフィルターを使用させる方法

を含むルールを追加するだけで、問題--use-any some_valueありません。例えば:

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

注:これ--use-anyは、ユーザースペースプラグインで(配列で定義された)でoption指定ebt_u_match reg.extra_opsされたものです。_any_opts

于 2012-02-23T15:04:46.487 に答える
1

カーネル モジュールを使用するには、ユーザー空間プログラム用の適切なプラグインを作成し、その後、それを呼び出すルールを挿入する必要もあります。

オプションがない場合は、.matchsizeパラメーターを指定しないでくださいstruct xt_match(0 を指定するのと同じ)。

于 2012-02-20T06:16:07.860 に答える