iptables勉強(2)
iptablesのtargetrの拡張
iptablesだいぶわかってきたので最小構成のtargetを書いてみた
構成ファイル
user空間用とkernel空間用の2種類のファイルを用意する必要がある
user空間用ファイル
iptablesコマンドを拡張するために /lib64/xtables/libに共有ライブラリを作成して配置する
名前はlibipt_<target名>.so
エントリポイントは_initという関数を作りxtables_targetを登録する
xtables.hはiptables-develパッケージに含まれている
#include <xtables.h> #include <stdio.h> static void MYLOG_help() { // printf("commandオプションがあればここに記述\n"); // iptables -j MYLOG --helpの時に表示される } static void MYLOG_print(const void *ip, const struct xt_entry_target *target, int numeric) { printf(" MYLOG"); // iptables -Lの時に表示される名前 } static struct xtables_target my_log_target = { .name = "MYLOG", .version = XTABLES_VERSION, .family = NFPROTO_IPV4, .help = MYLOG_help, .print = MYLOG_print }; void _init() { xtables_register_target(&my_log_target); }
作成したら共有ライブラリとしてコンパイルして/lib64/xtables/libに配置
gcc -fpic -shared ./libipt_MYLOG.c -o libipt_MYLOG.so
kernel空間用ファイル
user空間用ファイルに対応するカーネルモジュールを作成する
今回はヒットしたらログを出すだけ。
ユーザ空間のファイルとの対応はxt_targetのnameで行なっている
#include <linux/module.h> #include <linux/netfilter.h> #include <linux/netfilter/x_tables.h> MODULE_LICENSE("GPL"); static unsigned int log_mylog(struct sk_buff *skb, const struct xt_action_param *par) { printk(KERN_ALERT "run mylog\n"); return XT_CONTINUE; } static struct xt_target mylog_target __read_mostly = { .name = "MYLOG", .family = NFPROTO_IPV4, .target = log_mylog, .me = THIS_MODULE, }; static int __init mylog_init(void) { return xt_register_target(&mylog_target); } static void __exit mylog_exit(void) { xt_unregister_target(&mylog_target); } module_init(mylog_init); module_exit(mylog_exit);
作成したらカーネルモジュールをロード
insmod mylog.ko
iptables
user空間とkernel空間のファイルを作成すると、iptablesコマンドの-jオプションにて自分の作成したターゲットを指定できる
# iptables -A INPUT -j MYLOG # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination MYLOG all -- anywhere anywhere MYLOG Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
この状態でアクセスがあるとカーネルログにrun mylogが出力される