* patch: Port- and netscan detection for netfilter
@ 2007-03-15 13:29 Gladewitz, Robert (FH)
2007-03-16 15:40 ` Patrick McHardy
0 siblings, 1 reply; 12+ messages in thread
From: Gladewitz, Robert (FH) @ 2007-03-15 13:29 UTC (permalink / raw)
To: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 552 bytes --]
Helo,
in my Master-Theses I designed a new kernel- and netfilter module for
detection of net- and portscans. Now, the module is tested on more then
10 different firewall-installations. It's working without any problems
during the last 8 months.
Your can read the documentation on
http://ipt-portnetscan.sourceforge.net/. There is also a possibility to
download all versions of Kernel- and IpTables-Patches.
I would be pleased to see you integrated these patches into IpTables of
your use.
Looking forward to your answer
regards
[-- Attachment #2: iptables-1.3.7.patch --]
[-- Type: application/octet-stream, Size: 13654 bytes --]
diff -Naur iptables-1.3.7.org/extensions/.PORTNETSCAN-test iptables-1.3.7/extensions/.PORTNETSCAN-test
--- iptables-1.3.7.org/extensions/.PORTNETSCAN-test 1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.3.7/extensions/.PORTNETSCAN-test 2007-03-10 14:48:21.000000000 +0100
@@ -0,0 +1,3 @@
+#!/bin/sh
+# True if PORTNETSCAN is applied.
+[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h ] && echo PORTNETSCAN
diff -Naur iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.c iptables-1.3.7/extensions/libipt_PORTNETSCAN.c
--- iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.c 1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.3.7/extensions/libipt_PORTNETSCAN.c 2007-03-10 14:51:10.000000000 +0100
@@ -0,0 +1,330 @@
+/*
+ Name: libipt_PORTNETSCAN.h
+ Date: 16.05.2006
+ Last change: 03.03.2007
+ Version: 0.3
+
+
+ Shared library add-on to iptables to add port- and netscan detection
+
+ Copyright (C) Robert Gladewitz
+ Fachhochschule Heidelberg
+
+ This file is distributed under the terms of the GNU General Public
+ License (GPL). Copies of the GPL can be obtained from:
+ ftp://prep.ai.mit.edu/pub/gnu/GPL
+
+ 2006-05-26 Robert Gladewitz <gladewitz@gmx.de> : initial
+ 2006-08-03 Robert Gladewitz <gladewitz@gmx.de> : Correct wrong parameter deep to depth (misunderstanding parameter deep)
+ 2006-11-10 Robert Gladewitz <gladewitz@gmx.de> : Correct some spelling-mistakes
+ 2007-03-03 Robert Gladewitz <gladewitz@gmx.de> : Structure and documention correction
+*/
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ipt_PORTNETSCAN.h>
+/*
+########################################################################################################################
+######## local structs #################################################################################################
+########################################################################################################################
+*/
+static struct option opts[] = {
+ { "tree-depth", 1, 0, '1' },
+ { "trace-time", 1, 0, '2' },
+ { "clean-interval", 1, 0, '3' },
+ { "port-scan-quota", 1, 0, '4' },
+ { "net-scan-quota", 1, 0, '5' },
+ { "max-deny-entries", 1, 0, '6' },
+ { "max-trace-entries", 1, 0, '7' },
+ { "block-time", 1, 0, '8' },
+ { "combined-quota", 1, 0, '9' },
+ { "check-deny-entries", 0, 0, 'A' },
+ { 0 }
+};
+/* Initialize the target. */
+static void
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+ struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)m->data;
+
+ PNINFO->tree_depth = DEFAULTTREEDEPTH;
+ PNINFO->trace_time = DEFAULTTRACETIME;
+ PNINFO->clean_interval = DEFAULTCLEANINTERVAL;
+ PNINFO->port_scan_quota = DEFAULTPORTSCANQUOTA;
+ PNINFO->net_scan_quota = DEFAULTNETSCANQUOTA;
+ PNINFO->max_deny_entries = DEFAULTDENYLISTCOUNT;
+ PNINFO->max_trace_entries = DEFAULTENDNODECOUNT;
+ PNINFO->block_time = DEFAULTBLOCKTIME;
+ PNINFO->combined_quota = DEFAULTCOMBINEDQUOTA;
+ PNINFO->check_deny_entries = DEFAULTCHECKDENYENTRIES;
+}
+typedef struct _code {
+ char *c_name;
+ int c_val;
+} CODE;
+/*
+######## local defines ################################################################################################
+*/
+/* I know, its a very easy way without differend names */
+#define OPTSET01 1
+#define OPTSET02 2
+#define OPTSET03 4
+#define OPTSET04 8
+#define OPTSET05 16
+#define OPTSET06 32
+#define OPTSET07 64
+#define OPTSET08 128
+#define OPTSET09 256
+#define OPTSET10 512
+/*
+######## string_to_tree_depth ##########################################################################################
+*/
+static unsigned int string_to_tree_depth (char * STRING)
+{
+ unsigned int RC = DEFAULTTREEDEPTH;
+ unsigned int TEMPRC = 0;
+
+ if ( string_to_number (STRING,1,32,&TEMPRC) != -1 )
+ {
+ if ( TEMPRC == 1 || TEMPRC == 2 ||
+ TEMPRC == 4 || TEMPRC == 8 ||
+ TEMPRC == 16 || TEMPRC == 32 )
+ RC = TEMPRC;
+ else printf ("Warning: bad --tree-depth %s, use default %d\n",STRING,RC);
+ }
+ return RC;
+}
+/*
+######## parse ########################################################################################################
+*/
+static int parse( int c,
+ char **argv,
+ int invert,
+ unsigned int *flags,
+ const struct ipt_entry *entry,
+ unsigned int *nfcache,
+ struct ipt_entry_match **m)
+{
+ struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)(*m)->data;
+ unsigned int num;
+
+ switch (c) {
+ /* depth-tree OPTSET01*/
+ case '1':
+ if (*flags & OPTSET01)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --tree-depth twice");
+ PNINFO->tree_depth = string_to_tree_depth(optarg);;
+ *flags |= OPTSET01;
+ break;
+
+ case '2':
+ if (*flags & OPTSET02)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --trace-time twice");
+ if (string_to_number(optarg, 10, 36000, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --trace-time `%s' (10-3600)", optarg);
+ PNINFO->trace_time = num;
+ *flags |= OPTSET02;
+ break;
+
+ case '3':
+ if (*flags & OPTSET03)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --clean-interval twice");
+ if (string_to_number(optarg, 1, 60, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --clean-interval `%s' (1-60)", optarg);
+ PNINFO->clean_interval = num;
+ *flags |= OPTSET03;
+ break;
+
+ case '4':
+ if (*flags & OPTSET04)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --port-scan-quota twice");
+ if (string_to_number(optarg, 3, 1000, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --port-scan-quota `%s' (3-1000)", optarg);
+ PNINFO->port_scan_quota = num;
+ *flags |= OPTSET04;
+ break;
+
+ case '5':
+ if (*flags & OPTSET05)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --net-scan-quota twice");
+ if (string_to_number(optarg, 3, 1000, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --net-scan-quota `%s' (3-1000)", optarg);
+ PNINFO->net_scan_quota = num;
+ *flags |= OPTSET05;
+ break;
+
+
+ case '6':
+ if (*flags & OPTSET06)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --max-deny-entries twice");
+ if (string_to_number(optarg, 10, 2000, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --max-deny-entries `%s' (10-2000)", optarg);
+ PNINFO->max_deny_entries = num;
+ *flags |= OPTSET06;
+ break;
+
+
+ case '7':
+ if (*flags & OPTSET07)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --max-trace-entries twice");
+ if (string_to_number(optarg, 10, 20000, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --max-trace-entries `%s'(10-20000)", optarg);
+ PNINFO->max_trace_entries = num;
+ *flags |= OPTSET07;
+ break;
+
+ case '8':
+ if (*flags & OPTSET08)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --block-time twice");
+ if (string_to_number(optarg, 0, 172800, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --block-time `%s' (0-172800)", optarg);
+ PNINFO->block_time = num;
+ *flags |= OPTSET08;
+ break;
+
+ case '9':
+ if (*flags & OPTSET09)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --combined-quota twice");
+ if (string_to_number(optarg, 6, 10000, &num) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "bad --combined-quota `%s' (6-1000)", optarg);
+ PNINFO->combined_quota = num;
+ *flags |= OPTSET09;
+ break;
+
+ case 'A':
+ if (*flags & OPTSET10)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --check_deny_entries");
+ PNINFO->check_deny_entries = 1;
+ *flags |= OPTSET10;
+ break;
+
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+/*
+######## final_ceck ###################################################################################################
+*/
+static void final_check(unsigned int flags)
+{
+ /*
+ we dont need in this configuration
+ */
+}
+/*
+######## print ########################################################################################################
+Using is: print options
+*/
+static void
+print(const struct ipt_ip *ip,
+ const struct ipt_entry_match *m,
+ int numeric)
+{
+ const struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)m->data;
+
+ printf("PORTNETSCAN ");
+ printf("tree-depth: %u ", PNINFO->tree_depth);
+ printf("trace-time: %u ", PNINFO->trace_time);
+ printf("clean-interval: %u ", PNINFO->clean_interval);
+ printf("port-scan-quota: %u ", PNINFO->port_scan_quota);
+ printf("net-scan-quota: %u ", PNINFO->net_scan_quota);
+ printf("max-deny-entries: %u ", PNINFO->max_deny_entries);
+ printf("max-trace-entries: %u ", PNINFO->max_trace_entries);
+ printf("block-time: %u ", PNINFO->block_time);
+ printf("combined-quota: %u ", PNINFO->combined_quota);
+ if ( PNINFO->check_deny_entries != 0 )
+ printf("check-deny-entries ");
+}
+/*
+######## save #########################################################################################################
+Using: save iptables rules, we can parse for confuguring back
+*/
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_match *m)
+{
+ const struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)m->data;
+
+ printf("--tree-depth %u ", PNINFO->tree_depth);
+ printf("--trace-time %u ", PNINFO->trace_time);
+ printf("--clean-interval %u ", PNINFO->clean_interval);
+ printf("--port-scan-quota %u ", PNINFO->port_scan_quota);
+ printf("--net-scan-quota %u ", PNINFO->net_scan_quota);
+ printf("--max-deny-entries %u ", PNINFO->max_deny_entries);
+ printf("--max-trace-entries %u ", PNINFO->max_trace_entries);
+ printf("--block-time %u ", PNINFO->block_time);
+ printf("--combined-quota %u ", PNINFO->combined_quota);
+ if ( PNINFO->check_deny_entries != 0 )
+ printf("--check-deny-entries ");
+}
+/*
+######## help #########################################################################################################
+Using: print help (iptables --help)
+*/
+static void help(void)
+{
+ printf(
+"PORTNETSCAN v%s options:\n"
+" --tree-depth treedepth (default:4) Use this treedepth for trace tree\n\n"
+" --trace-time tracetime (default:120) Timeinterval in seconds for source-entries (120 =P 2 minutes)\n\n"
+" --clean-interval cleanint (default:1) Timeinterval in seconds for checking end deleting old entries\n\n"
+" --port-scan-quota portscanq (default:10) if per source count_dstports/count_dst > portscanq src is positive\n\n"
+" --net-scan-quota netscanq (default:10) if per source count_dst/count_dstport > netscanq src is positive\n\n"
+" --combined-quota compinedq (default:50) if per source count_dst+count_dstport > combinedq src is positive\n\n"
+" --max-deny-entries maxdenyc (default:500) Max entries in denylist\n\n"
+" --max-trace-entries mactracec (default:20000) Max entries in trace-tree/trace-list\n\n"
+" --block-time blocktime (default:3600) Timeinterval in seconds where the src ist blocked, if we found a port- or netscan or overtaken combined-quota\n\n"
+" --check-deny-entries If set, only Check denylist (don't lock vor trace-entries)\n\n",
+IPTABLES_VERSION);
+}
+/*
+########################################################################################################################
+######## iptables ######################################################################################################
+########################################################################################################################
+*/
+static struct iptables_match PORTNETSCAN = {
+ .next = NULL,
+ .name = "PORTNETSCAN",
+ .version = IPTABLES_VERSION,
+ .size = IPT_ALIGN(sizeof(struct ipt_PORTNETSCAN_info)),
+ .userspacesize = IPT_ALIGN(sizeof(struct ipt_PORTNETSCAN_info)),
+ .help = &help,
+ .init = &init,
+ .parse = &parse,
+ .final_check = &final_check,
+ .print = &print,
+ .save = &save,
+ .extra_opts = opts
+};
+/*
+######## init #########################################################################################################
+*/
+void _init(void)
+{
+ register_match(&PORTNETSCAN);
+}
diff -Naur iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.man iptables-1.3.7/extensions/libipt_PORTNETSCAN.man
--- iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.man 1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.3.7/extensions/libipt_PORTNETSCAN.man 2007-03-10 14:48:21.000000000 +0100
@@ -0,0 +1,7 @@
+This modul can find port-, net- and compinedscan situations for protocol types udp and tcp. At the moment, it support only ipv4 protocols. It works whith enviroment-set per parameter-set.
+Using:
+iptables -A FORWARD -p tcp -m PORTNETSCAN --trace-time 3000 --check-deny-entries -j DROP
+# ...
+# Allow-Rules
+# ...
+iptables -A FORWARD -p tcp -m PORTNETSCAN --trace-time 3000 -j DROP
[-- Attachment #3: linux-2.6.20.2.patch --]
[-- Type: application/octet-stream, Size: 148927 bytes --]
diff -Naur linux-2.6.20.2.org/Documentation/ipt_PORTNETSCAN.txt linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt
--- linux-2.6.20.2.org/Documentation/ipt_PORTNETSCAN.txt 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt 2007-03-10 14:33:15.000000000 +0100
@@ -0,0 +1,389 @@
+Allgemein Informationen zum Modul ipt_PORTNETSCAN
+-------------------------------------------------
+
+Erkennung von Port-, Net- oder Combinedscans.
+
+Synopsis Aufruf des Moduls ipt_PORTNETSCAN
+------------------------------------------
+
+Das Modul wird durch eine IpTables Filterregel mittels der Option
+-m PORTNETSCAN aufgerufen.
+
+iptables [iptables Optionen] -m PORTNETSCAN [Optionen]
+
+Einschränkungen oder Filtervorgaben können in IpTables durch alle
+implementierten IpTables Optionen definiert werden. Das Modul wird
+nur aufgerufen, wenn die zuvor definierten Filter oder Einschränkungen
+in den IpTables Optionen gültig sind.
+
+
+Überblick über die Optionen
+---------------------------
+
+--tree-depth [1|2|4|8|16|32]
+Standard: --tree-depth 4
+Diese Option gibt die Baumtiefe des Suchbaumes (Suchindex) (trace-tree /
+Überwachungsliste) an. Bei einer angegeben Baumtiefe von 1 wird eine
+einfache verkettete Liste als Suchindex verwendet. Bei eigenen
+Testreihen hat sich eine Baumtiefe von vier als Optimum herausgestellt.
+Bei den Tests wurde aber von mehr als 1000 gleichzeitigen Verbindungen
+ausgegangen.
+
+--trace-time [Sekunden] (10-3600)
+Standard: --trace-time 120 (2 Minuten)
+Die Option trace-time gibt die Zeit in Sekunden an, welche eine Quelladresse
+überwacht wird. Solange Pakete durch die Regel überprüft werden, beginnt
+die Überwachungszeit von neuem. Dies bedeutet, dass z.B. bei einem Wert von
+20 in dieser Option der Überwachungseintrag der Quelladresse erst dann
+entfernt wird, wenn dieser 120 Sekunden keine Prüfung mehr erfordert hat,
+d.h. dass in dieser Zeitspanne kein Paket durch die IpTables Regel zur
+Überprüfung an das Modul gesendet wurde. Dies ist in der Regel der Fall,
+wenn der Rechner keine Verbindung mehr zum Zielsystem hat.
+
+--block-time [Sekunden] (0-172800)
+Standard: --block-time 3600 (1 Stunde)
+Die Option block-time gibt die Zeit in Sekunden an, die die Quelladresse eines
+Rechners gesperrt wird, falls eine der definierten Schwellwerte (Quotas)
+erfüllt ist. Der Rechner wird im Falle des Überschreitens eines Schwellwertes
+(Quota) aus den überwachten Einträgen gelöscht und in die Ablehnungsliste
+verschoben. Diese Liste ist eine normale verkettete Liste im Speicher und
+wird nicht zusätzlich indiziert.
+
+--clean-interval [Sekunden] (1-60)
+Standard: --clean-interval 1 (1 Sekunde)
+Diese Option legt das Intervall fest, nach dem veraltete Einträge aus den
+Überwachungs- und Ablehnungslisten gelöscht werden. Zusätzlich ist im Kernel
+noch ein globales Intervall festgelegt, nach dem veraltete Einträge aller
+Konfigurationsumgebungen freigegeben werden.
+
+--max-deny-entries [Anzahl] (10-2000)
+Standard: --max-deny-entries 10
+Die Option max-deny-entries legt fest, wie viele Einträge maximal pro
+Konfigurationsumgebung in der Ablehnungsliste gespeichert werden. Wenn die die
+maximal definierte Anzahl überschritten ist, wird der älteste Eintrag aus der
+Ablehnungsliste entfernt und der neue hinzugefügt. Da diese Liste nicht durch
+einen Baum indiziert wird, darf der Wert nicht zu groß definiert werden, da
+dies sonst Einfluss auf die Netzwerkperformance nimmt.
+
+--max-trace-entries [Anzahl] (10-20000)
+Standard: --max-trace-entries 3000
+Durch die Option max-trace-entries wird festgelegt, wie viele Einträge maximal
+pro Konfigurationsumgebung in der Überwachungslisteliste gespeichert werden.
+Wenn dieser Wert überschritten wird, wird der älteste Eintrag aus der Liste
+entfernt und der neue hinzugefügt.
+
+--port-scan-quota [Quota] (3-1000)
+Standard: --port-scan-quota 10
+Diese Option legt fest, ab welchem Schwellwert (Quota) ein Portscan erkannt
+wird.
+Ein Portscan wird angenommen bei Erfüllung folgender Voraussetzung:
+(Zielports / Zieladressen) > port-scan-quota
+
+--net-scan-quota [Quota] (3-1000)
+Standard: --net-scan-quota 10
+Mittels dieser Option wird festgelegt, ab welchem Schwellwert (Quota) ein
+Netscan erkannt wird.
+Ein Netscan wird angenommen bei Erfüllung folgender Voraussetzung:
+(Zieladressen / Zielports) > net-scan-quota
+
+--combined-quota [Quota] (6-1000)
+Standard: --combined-quota 50
+Durch diese Option wird festgelegt, ab welchem Schwellwert (Quota) ein
+Combined-Scan erkannt wird.
+Ein Combined-Scan wird angenommen bei Erfüllung folgender Voraussetzung:
+(Zieladressen + Zielports) > combined-quota
+
+--check_deny_entries
+Standard <Kein Parameter>
+Wenn diese Option angegeben wird, wird geprüft, ob sich die Quelladresse
+in der Ablehnungsliste befindet. Für diesen Fall wird ein positiver
+Rückgabewert an IpTables zurückgeliefert.
+
+Unterscheidung Einsatzgebiete
+Wichtig bei der Verwendung des Moduls ist die Reihenfolge der IpTables
+Regeln. Bei falscher Verwendung kann dies die Dienste oder Zugriffe zum
+und vom Internet stark einschränken.
+Für die Verwendung des Moduls werden zwei Szenarien vorgeschlagen. Diese
+unterscheiden sich grundlegend und werden nachfolgend genauer betrachtet.
+
+Anwendung des Moduls zur Überwachung abgelehnter Pakete
+In der ersten Betrachtung des Moduleinsatzes wird von einer Firewall mit
+bereits klar eingeschränkten Filterregeln für die genutzten Dienste und
+Anwendungen ausgegangen. Die Verwendung des Moduls erweitert die Firewall
+um die dynamische Erkennung und Ablehnung von Port-, Net- oder Combined-Scans.
+Dadurch können auch Dienste, die in der Firewall für bestimmte Server erlaubt
+sind, vor einem Angreifer verborgen werden. Gleichzeitig ist gewährleistet,
+dass die Dienste ohne Einschränkungen genutzt werden können.
+
+Für dieses Szenario müssen folgende Regeln eingehalten werden:
+
+1. Das Modul ist nur voll funktionsfähig, wenn die Firewall nach dem Konzept
+ "Alles was nicht explizit zugelassen wird ist verboten" aufgebaut ist.
+2. Vor den vorhanden Regeln muss die Option "--check-deny-entries" beim Aufrufen
+ des Module gesetzt werden.
+3. Nach diesen Regeln müssen alle Regeln für erlaubten Netzwerkverkehr folgen.
+4. Am Ende der abzuarbeitenden Regelliste von IpTables muss das Modul ohne die
+ Option "--check-deny-entries" aufgerufen werden.
+5. Ansonsten müssen die gleichen Konfigurationsparameter wie zuvor verwendet
+ werden, um die selbe Konfigurationsumgebung in allen Aufrufen des Moduls zu
+ besitzen.
+
+In der folgenden Skizze wird die korrekte Verwendung dargestellt:
+
+Abzuarbeitende
+IpTables
+Regeln
+
+ | ---------------------------------------------------------------
+ | | iptables -A ... -m PORTNETSCAN --check-deny-entries -j DROP | --
+ | --------------------------------------------------------------- |
+ | | |
+ | V |
+ | --------------------------------------- |
+ | | iptables -A ... | -- |
+ | --------------------------------------- | |
+ | --------------------------------------- | |
+ | | iptables -A ... | -| -------- |
+ | --------------------------------------- |->|ACCEPT| |
+ | --------------------------------------- | -------- |
+ | | iptables -A ... | -| |
+ | --------------------------------------- | |
+ | --------------------------------------- | |
+ | | ... | -- |
+ | --------------------------------------- |
+ | | |
+ | V |
+ | --------------------------------------------------------------- |
+ | | iptables -A ... -m PORTNETSCAN -j DROP | --
+ | --------------------------------------------------------------- | ------
+ | --------------------------------------------------------------- |->|DROP|
+ | | iptables -A ... -J DROP | -- ------
+ | ---------------------------------------------------------------
+ V
+
+Anwendung des Moduls zur Überwachung bestimmter Dienste oder Netzbereiche
+-------------------------------------------------------------------------
+
+Eine weitere Einsatzmöglichkeit stellt die Verwendung des Moduls zur reinen
+Überwachung der Firewall dar. Andere Filterregeln, die für die benötigten
+Dienste in der Firewall gebraucht werden, werden erst nach dem Aufruf des
+Moduls PORTNETSCAN abgearbeitet.
+Vor diesen Regeln müssen Ausnahmen definiert werden, die Mehrfachverbindungen
+erlauben, um fehlerhaft abgelehnte Pakete zu verhindern.
+
+Das nachfolgende Schaubild beschreibt die Reihenfolge der Abarbeitung für
+diesen Einsatzzweck:
+
+Abzuarbeitende
+IpTables
+Regeln
+
+ | ---------------------------------------
+ | | iptables -A ... (Ausnahme1) | --
+ | --------------------------------------- |
+ | --------------------------------------- |
+ | | iptables -A ... (Ausnahme1) | -| --------
+ | --------------------------------------- |->|ACCEPT|
+ | --------------------------------------- | --------
+ | | iptables -A ... (AusnahmeXXX) | --
+ | ---------------------------------------
+ | |
+ | V
+ | ---------------------------------------------------------------
+ | | iptables -A ...(Einschränkungen) -m PORTNETSCAN -j DROP | --
+ | --------------------------------------------------------------- |
+ | --------------------------------------- |
+ | | iptables -A ... | -- |
+ | --------------------------------------- | |
+ | --------------------------------------- | |
+ | | iptables -A ... | -| -------- |
+ | --------------------------------------- |->|ACCEPT| |
+ | --------------------------------------- | -------- |
+ | | iptables -A ... | -| |
+ | --------------------------------------- | |
+ | --------------------------------------- | |
+ | | ... | -- |
+ | --------------------------------------- |
+ | --------------------------------------------------------------- | ------
+ | | iptables -A ... -J DROP | --->|DROP|
+ | --------------------------------------------------------------- ------
+
+Bei Verwendung des Moduls für dieses Szenario muss genau geprüft werden, für
+welche Server oder Clients im internen Netz Mehrfachverbindungen erlaubt sein
+müssen. Zudem sollte eine eindeutige Einschränkung in der aufgerufenen
+IpTables Regel erfolgen. Einschränkungen können zum Bespiel gesetztes SYN-Bit
+einer TCP Verbindung oder die Zielports einer Anwendung sein.
+
+Bei diesem Einsatzzweck empfiehlt sich die Verwendung mehrerer
+Konfigurationsumgebungen und eine Aufteilung in verschiedene Regeln, die die
+Zustände der Firewall erkennen lassen.
+
+Informationen über den Modulzustand im proc-Dateisystem
+-------------------------------------------------------
+In der aktuellen Implementierung des Kernelmoduls ipt_PORTNETSCAN wird beim
+Laden automatisch der Proc-Eintrag /proc/net/stat/portnetscan erstellt. In
+diesem befinden sich alle Informationen über den Status des Moduls.
+
+Durch die Anzahl der überwachten Einträge kann die Anzahl der ausgegebenen
+Zeilen sehr groß werden. Aus diesem Grund werden die Zeilen je nach
+Informationsinhalt mit einem definierten Anfangsbuchstaben zur Identifikation
+ausgegeben:
+
+ G - Anzahl globale Konfigurationsumgebungen
+ U - Aktuelle Zeit (Unixzeit)
+ J - Aktuelle Kernelzeit (jiffies)
+ C - Nächster Globaler Cleanup-Task (jiffies)
+ L - Eintrag Konfigurationsumgebung
+ D - Eintrag Ablehnungsliste
+ T - Eintrag Überwachungsliste
+
+Nachfolgend wird eine Beispielausgabe mit nur einem überwachten Eintrag
+dargestellt:
+
+# IpTables PORTNETSCAN MODUL
+# --------------------------
+#
+G Count_Global_Conf: 1
+U Updating_Time(Unix): 1151670238
+#
+J Updating_Time(jiffies): 170718608
+C Next_Cleanup_Time(jiffies): 170725409
+#
+# Conf_Entries
+# ------------
+#
+# confn/tree-depth/trace-time/clean-interval/port-scan-quota/net-scan-quota/combined-quota/max-deny-entries/max-trace-entries/block-time/tree-count/endnode-count/denylist-count
+L 0 4 3600 1 4 4 8 50 10000 36000 20 5 5
+#
+# Deny_Entries
+# ------------
+#
+# confn/ipaddress/starttime/endtime/count/reason
+D 0 202.99.174.208 1151666423 1151702423 6 netscan_detected
+D 0 220.45.224.26 1151666512 1151702512 499 netscan_detected
+D 0 222.76.210.149 1151666756 1151702756 16 netscan_detected
+D 0 206.155.58.83 1151667516 1151703516 105 netscan_detected
+D 0 64.114.81.195 1151668641 1151704641 161 netscan_detected
+#
+# Trace_Entries
+# -------------
+#
+# confn/ipaddress/firsttime/lasttime/count/countdst/countdpt
+T 0 219.136.206.12 1151665723 1151668290 6 3 1
+T 0 195.22.30.100 1151667986 1151667995 3 1 1
+T 0 80.247.193.215 1151668045 1151668488 2 2 1
+T 0 193.189.68.70 1151668446 1151668449 2 1 1
+T 0 65.214.44.227 1151669558 1151669567 3 1 1
+
+
+Alle Variablen werden mit dem Zeichen ":" getrennt, alle Listenwerte werden
+durch ein TAB getrennt. Somit können in Skripten oder externen Programmen leicht
+Aussagen über den Zustand des Moduls getroffen werden. Für die Listeneinträge
+der Ablehnungsliste (Deny_Entries) und der Überwachungsliste (Trace_Entries)
+wird immer die Konfigurationsumgebung (confn) mit ausgegeben. Wie weiter oben
+schon angemerkt, kann es durchaus vorkommen, dass eine Quelladresse mehrfach
+auftaucht, allerdings pro einer Konfigurationsumgebung nur einmal!
+
+Ein Beispiel für die praktische Anwendung
+-----------------------------------------
+Im diesem Beispiel werden nur Pakete und Verbindungen überwacht, die nach den
+Regeln zum Erlauben von Diensten und Anwendungen der Firewall nicht zugelassen
+wurden. Die folgende Umgebung wird folgende angenommen:
+
+Netz DMZ: 1.1.1.0/24
+Netzwerkkarten äußerer Router:
+ - eth0: zum Internet
+ - eth1: zur DMZ
+Webserver Standard http Port 80:
+ - 1.1.1.4
+ - 1.1.1.43
+DNS-Server
+ - 1.1.1.3
+Proxy-Server (http-Proxy)
+ -1.1.1.2
+
+Das nachfolgende Beispielskript der Firewall wird ohne Verwendung zusätzlich
+erstellter Ketten für IpTables oder Datenstrukturen in Skripten dargestellt,
+um die wesentlichen Inhalte hervorzuheben und die Lesbarkeit zu erhöhen.
+
+#!/bin/bash
+#...
+##############################################################################
+# PORTNETSCAN: Überprüfung Ablehnungsliste
+iptables -A FORWARD -i eth0 -o eth1 -m PORTNETSCAN --check-deny-entries\
+ --trace-entries 12000 -j DROP
+#
+# Standard Paketfilterregeln
+##############################################################################
+# Webserver 1.1.1.4
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -d 1.1.1.4/32 --dport 80 \
+ --sport 1024:
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.4/32 --sport 80 \
+ --dport 1024: !--syn
+# Webserver 1.1.1.43
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -d 1.1.1.43/32 \
+ --dport 80 --sport 1024:
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.43/32 \
+ --sport 80 --dport 1024: !--syn
+##############################################################################
+# DNS Server 1.1.1.3
+# DNS: Server - Server
+iptables -A FORWARD -j ACCEPT -p UDP -i eth0 -o eth1 -d 1.1.1.3/32 --sport 53 \
+ --dport 53
+iptables -A FORWARD -j ACCEPT -p UDP -i eth1 -o eth0 -s 1.1.1.3/32 --sport 53 \
+ --dport 53
+# DNS: Server - Client
+iptables -A FORWARD -j ACCEPT -p UDP -i eth0 -o eth1 -d 1.1.1.3/32 --sport 53 \
+ --dport 1024:
+iptables -A FORWARD -j ACCEPT -p UDP -i eth1 -o eth0 -s 1.1.1.3/32 \
+ --sport 1024: --dport 53
+# DNS: Client - Server
+iptables -A FORWARD -j ACCEPT -p UDP -i eth0 -o eth1 -d 1.1.1.3/32 \
+ --sport 1024: --dport 53
+iptables -A FORWARD -j ACCEPT -p UDP -i eth1 -o eth0 -s 1.1.1.3/32 \
+ --sport 53 --dport 1024:
+##############################################################################
+# Proxy Server (nur Standardverbindungen Port 80 und 443)
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.2/32 \
+ --sport 1024: --dport 80
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -s 1.1.1.2/32 \
+ --dport 1024: --sport 80 !--syn
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.2/32 \
+ --sport 1024: --dport 443
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -s 1.1.1.2/32 \
+ --dport 1024: --sport 443 !--syn
+# Ende aller Standard-Regeln
+##############################################################################
+# PORTNETSCAN Überprüfung Auffälligkeiten
+iptables -A FORWARD -i eth0 -o eth1 -m PORTNETSCAN --trace-entries 12000 \
+ -j DROP
+##############################################################################
+# Rest Ablehen
+iptables -A FORWARD -j DROP
+##############################################################################
+# Policy-Standard-Regel setzen (ist zwingend nicht norwendig, da die letzte
+# Regel schon alle Pakete "DROP"
+IPTABLES -P FORWARD DROP't
+
+
+In diesem Skript wurde zusätzlich die Veränderung der Parametrisierung des
+Moduls dargestellt. Der Parameter "--trace-entries" wurde auf den Wert 12000
+gesetzt. Dies muss in beiden Aufrufen des Moduls geschehen, damit die beiden
+Aufrufe in derselben Konfigurationsumgebung durchgeführt werden.
+
+Im ersten Aufruf mit den Parametern
+ -m PORTNETSCAN --check-deny-entries --trace-entries 12000
+wird nur geprüft, ob sich die Quelladresse des Rechners bereits in der
+Ablehnungsliste befindet. Hierbei wird nicht in den Überwachungseinträgen
+nachgesehen, ob eine Auffälligkeit wie Port-, Net-, oder Combinedscan
+vorhanden ist.
+
+Im zweiten Aufruf, der nach den Standardregeln ausgeführt wird, wird das
+Modul mit den Parametern
+ -m PORTNETSCAN --trace-entries 12000
+aufgerufen. Jetzt wird vom Modul geprüft, ob eine Auffälligkeit vorhanden
+ist und einer der gesetzten Schwellwerte überschritten wird. Sollte dies der
+Fall sein, wird der Eintrag in die Ablehnungsliste verschoben. Ab diesem
+Moment wird beim Aufrufen der Funktion des Moduls an IpTables ein positives
+Ereignis für diese Quelladresse zurückgemeldet. Bei Angabe von "-j DROP" wird
+das Paket ni diesem Fall von IpTables im Kernel verworfen.
diff -Naur linux-2.6.20.2.org/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h linux-2.6.20.2/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h
--- linux-2.6.20.2.org/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h 2007-03-10 14:57:15.000000000 +0100
@@ -0,0 +1,388 @@
+/*
+ Name: ipt_PORTNETSCAN.h
+ Date: 16.05.2006
+ Last change: 03.03.2007
+ Version: 0.3
+
+ Bemerkung:
+ Detect port- or netscans
+
+ Copyright (C) Robert Gladewitz
+ Fachhochschule Heidelberg
+
+ This file is distributed under the terms of the GNU General Public
+ License (GPL). Copies of the GPL can be obtained from:
+ http://www.gnu.org/licenses/gpl.html
+
+ 2006-05-26 Robert Gladewitz <gladewitz@gmx.de> : initial
+ 2006-05-30 Robert Gladewitz <gladewitz@gmx.de> : start testingseries in simulations networks in different situations
+ 2006-06-05 Robert Gladewitz <gladewitz@gmx.de> : adding --check-deny-enttries
+ 2006-06-22 Robert Gladewitz <gladewitz@gmx.de> : fix bug: no deleting emty conft-Entries
+ 2006-06-22 Robert Gladewitz <gladewitz@gmx.de> : fix bug: no deleting emty conft-entries
+ 2006-07-06 Robert Gladewitz <gladewitz@gmx.de> : Support fpr new structure for iptables in kernel 2.6.17
+ 2006-08-03 Robert Gladewitz <gladewitz@gmx.de> : Correct wrong parameter deep to depth (misunderstanding parameter deep)
+ 2007-03-03 Robert Gladewitz <gladewitz@gmx.de> : Change some structures and documentations
+*/
+
+/*
+############################################################################################################################################
+Global Defs
+############################################################################################################################################
+*/
+
+#ifndef portnetscan_H
+#define portnetscan_H
+/*
+############################################################################################################################################
+EigeneDefault-Definitionen
+############################################################################################################################################
+*/
+
+// Unabhängige Typdefinitionen
+typedef u_int32_t IpV4Address; /* Typ für eine IP-Adresse (IPV4) ist ein 32 Bit Integer */
+typedef u_int16_t IpV4Port; /* Typ für ein IP Port (IPV4) ist ein 16 Bit Integer */
+
+// StandardDefinitionen
+#define DEFAULTTREEDEPTH 4 /* StandardTiefe des verwendeten Baumes */
+#define DEFAULTDEBUGLEVEL 0 /* Debuglevel */
+#define DEFAULTTRACETIME 120 /* 10 Minuten Überwachen per Default (600 Sekunden = 10 Minuten) */
+#define MAXTRACETIME 3600 /* 1 Stunde Maximal Überwachungszeit (3600 Sekunden = 1 Stunde) */
+#define DEFAULTCLEANINTERVAL 1 /* Jede Sekunde soll geprüft werden, ob Einträge veraltet sind */
+#define MAXTCLEANINTERVAL 60 /* Maxmialer Wert für clean-interval */
+#define MAXUINT32 4294967295 /* Maximaler 32 BIT Unsigned Int */
+#define MAXENDNODEENTRY 9999 /* Maximale Länge in Vektoren der Werte DPT und DST einer EndNode */
+#define DEFAULTPORTSCANQUOTA 10 /* Portscan Erkennung: Standardwert für Verhältnis (Schwellwert) von Zieladresse zu Zielport (Zielports/Zieladressen) */
+#define MAXPORTSCANQUOTA 1000 /* Maximalwert für Schwellwert zur Portscan Erkennung */
+#define DEFAULTNETSCANQUOTA 10 /* Netscan Erkennung: Standardwert für Verhältnis (Schwellwert) von Zielport zur Zieladresse (Zieladressen/Zielports) */
+#define MAXNETSCANQUOTA 1000 /* Maximalwert für Schwellwert zur Netscan Erkennung */
+#define DEFAULTBLOCKTIME 3600 /* Zeit, die ein Host als blockiert gilt, falls ein Port- oder Netscan erkannt wird */
+#define MAXBLOCKTIME 172800 /* Maximale Zeit für blocken einer Quelladresse (172800 = 2 Tage) */
+#define DEFAULTDENYLISTCOUNT 10 /* Default Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
+#define MINDENYLISTCOUNT 10 /* Minimale Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
+#define MAXDENYLISTCOUNT 2000 /* Maximale Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
+#define MINENDNODECOUNT 10 /* Minimale Anzahl an überwachten Einträgen */
+#define MAXENDNODECOUNT 20000 /* Maximale Anzahl an überwachten Einträgen */
+#define DEFAULTENDNODECOUNT 10000 /* Standard Anzahl an überwachten Einträgen */
+#define GLOBALCLEANUP 30 /* Globaler Cleanup-Interval */
+#define DEFAULTCOMBINEDQUOTA 50 /* Schwellwert für Zielhost + Zielports eines Quellrechners */
+#define MAXCOMBINEDQUOTA 1000 /* Maximaler Schwellwert für Zielhost + Zielports eines Quellrechners */
+#define KERNELLINEMAX 1024 /* Maximale Länge einer Ausgabezeile für den Kernel (proc-Aufruf) */
+#define KERNELPAGESIZE 4096 /* Pagesize im Kernel */
+#define DEFAULTCHECKDENYENTRIES 0 /* Nur Deny-Liste überprüfen */
+
+// Erkannte Probleme
+#define REASONPORTSCAN 1 /* Portscan wurde erkannt */
+#define REASONNETSCAN 2 /* Netscan wurde erkannt */
+#define REASONCOMPINED 4 /* Combined Scan wurde erkannt */
+#define REASONUNKNOWN 1024
+/*
+############################################################################################################################################
+Debuging and Testing
+############################################################################################################################################
+*/
+
+
+#ifdef __KERNEL__
+#define _malloc(ptr,prio) kmalloc (ptr, prio)
+#define _free(ptr) kfree(ptr)
+#define _printf printk
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+
+#else
+#define _malloc(ptr,prio) malloc (ptr)
+#define _free(ptr) free(ptr)
+#define _printf printf
+#endif
+
+
+
+
+
+
+/*
+############################################################################################################################################
+Definitionen für Netfilter / IpTables / Umgebungen
+############################################################################################################################################
+*/
+/*
+Beschreibung
+
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: ipt_PORTNETSCAN_info
+ Conv: IPTABLES
+ Typ: verkettete Liste
+ Info: Datenübergabe zwischen IpTables und dem Kernelmodul
+*/
+struct ipt_PORTNETSCAN_info
+{
+ unsigned int tree_depth;
+ unsigned int trace_time;
+ unsigned int clean_interval;
+ unsigned int port_scan_quota;
+ unsigned int net_scan_quota;
+ unsigned int max_deny_entries;
+ unsigned int max_trace_entries;
+ unsigned int block_time;
+ unsigned int combined_quota;
+ unsigned short check_deny_entries;
+};
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscanConf
+ Conv: PortNetScan
+ Typ: Einfacher Struct (Angehängt an einer PortNetscanEnv-Liste)
+ Info: Für jede unterschiedliche Parameterübergabe wird eine Eigene
+ Konfigurationsumgebung erstellt, die selbst auch alle Parameter (Einstellungen)
+ enthällt. An diese angeknübft werden dann die SuchListen und Suchbäume
+*/
+struct PortNetscanConf
+{
+ struct TreeNode * RootEntry; // Zeiger auf ersten Baumknoten (Siehe TreeNode)
+ struct TreeEndNode * FirstEndNode; // Zeiger auf ersten überwachten Eintrag (Siehe TreeEndNode)
+ struct TreeEndNode * LastEndNode; // Zeiger auf letzen überwachten Eintrag (Siehe TreeEndNode)
+ unsigned int EndNodeCount; // Anzahl von überwachten Einträgen
+ unsigned short TreeDepth; // Baumtiefe in dieser Konfigurationsumgebung
+ unsigned int TraceTime; // Überwachungszeit in dieser Konfigurationsumgebung
+ unsigned int CleanInterval; // Aufräum-Interval in dieser Konfigurationsumgebung
+ unsigned int NetscanQuota; // Verhältnis-Maximum zur Erkennung eines Netscans (Net/Port) in dieser Konfigurationsumgebung
+ unsigned int PortscanQuota; // Verhältnis-Maximum zur Erkennung eines Portscans (Port/Net) in dieser Konfigurationsumgebung
+ unsigned int CombinedQuota; // Kombiniertes Maximum in dieser Konfigurationsumgebung
+ unsigned int BlockTime; // Blockierte Zeit eines gesperrten Rechners in dieser Konfigurationsumgebung
+ unsigned int TreeCount; // Anzahl verwendeter Baumkonten in dieser Konfigurationsumgebung
+ unsigned int DenyListCount; // Einzahl Einträge in Liste blockierter Hosts in dieser Konfigurationsumgebung
+ unsigned int MaxDenyListCount; // Maximale Einträge in Liste blockierter Hosts in dieser Konfigurationsumgebung
+ unsigned int MaxEndNodeCount; // Maximale Einträge in Liste überwachter Einträge in dieser Konfigurationsumgebung
+ time_t LastClean; // Letzter Aufräumvorgang in dieser Konfigurationsumgebung
+ struct DenyList * FirstDenyListEntry; // Zeiger auf ersten Eintrag in Liste blockierte Hosts in dieser Konfigurationsumgebung
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: struct PortNetscanEnv
+ Conv: PortNetScan / IpTables
+ Typ: verkettete Liste
+ Info: Übergeordete verkettete Liste für PortNetscanConf. Die Attribute aus IpTables
+ wurden hier mit Absicht in dem Namensraum von IpTables angegeben (klein,
+ mit _ getrennt, welches in IpTables selbst mit - getrennt wurde)
+*/
+struct PortNetscanEnv
+{
+ struct PortNetscanEnv * Next; // Nächster Eintrag in verketteter Liste ( NULL wenn letzter Eintrag)
+ struct PortNetscanEnv * Prior; // Vorheriger Eintrag in verketteter Liste ( NULL wenn erster Eintrag)
+ struct PortNetscanConf ConfEntries; // Konfigurations-Struct
+ unsigned int tree_depth; // IpTables: tree-depth
+ unsigned int trace_time; // IpTables: trace-time
+ unsigned int clean_interval; // IpTables: clean-interval
+ unsigned int port_scan_quota; // IpTables: port-scan-quota
+ unsigned int net_scan_quota; // IpTables: net-scan-quota
+ unsigned int max_deny_entries; // IpTables: max-deny-entries
+ unsigned int max_trace_entries; // IpTables: max-trace-entries
+ unsigned int block_time; // IpTables: block-time
+ unsigned int combined_quota; // IpTables: combined-quota
+ time_t LastUse; // Letzter Aufruf (Überprüfung Ablehnungsliste/Überwachungsliste)
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: struct KernelOutLinePuffer
+ Conv: Kernel/IpTables
+ Typ: Einfacher Struct
+ Info: Speichert für ein proc_read die Zeilen zwischen
+ Interner Name: Kernelausgabeliste
+*/
+struct KernelOutLinePuffer
+{
+ char Line[KERNELLINEMAX]; // Puffer für Inhalt der Kernelzeile (String)
+ struct KernelOutLinePuffer * Next; // Zeiger auf nächstes Element in Kernelausgabeliste
+};
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: struct IptGlobalConfStruct
+ Conv: PortNetScan
+ Typ: Einfacher Struct
+ Info: Wird statisch initialisiert (in ModulInit) und speichert globale Einstellungen
+*/
+struct IptGlobalConfStruct
+{
+ struct PortNetscanEnv * FirstPortNetscan; // Speichert den ersten Konfigurationeintrag (Konfigurationsumgebung)
+ struct KernelOutLinePuffer * FirstOutLine; // Kernelausgabeliste: Bei proc_read-Aufruf ist dies der Zeiger auf das erste Element der noch auszugebenen Liste
+ struct KernelOutLinePuffer * LastPrintOutLine; // Kernelausgabeliste: Letztes ausgegebenes Elemet
+ struct KernelOutLinePuffer * LastAddOutLine; // Kernelausgabeliste: Letztes hinzugefügtes Element
+ unsigned int FailBuffer; // Kernelausgabeliste: Bei nicht ausreichenden Puffer, werden hier die Anzahl der bereits verarbeiteten Bytes angegeben
+ unsigned int Conf_Count; // Anzahl der Konfigurationseinträge
+ time_t LastCleanup; // Letzer globaler Aufräumablauf (Unix-Zeit)
+};
+
+
+
+
+// Beschreibung Unabhängige Stukturen
+/*
+ TreeNode(Root)
+ |
+ ---------------------------
+ | |
+ TreeNode TreeNode
+ .... .... .... |
+ ---------
+ |
+ TreeNode
+ .... |
+ ----------
+ |
+ TreeNode
+ .... |
+ ---------
+ |
+ EndTreeNode <--> EndTreeNode <-->EndTreeNode <--> EndTreeNode
+ | - TreeEndNodeEntries | - TreeEndNodeEntries
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: struct TreeEnd
+ Conv: PortNetScan
+ Typ: verkettete BaumListe
+ Info: Suchbaum, mit angepasster Tiefe
+*/
+
+struct TreeNode
+{
+ struct TreeNode * Parent; // übergeordneter Eintrag in Suchbaum (NULL, wenn in oberster Ebene)
+ void * Childs; // untergeordneter Eintrag
+ struct TreeNode * Prior; // vorheriges Element in gleicher Hierachieebene (NULL, wenn erster Eintrag in Hierachieebene)
+ struct TreeNode * Next; // nächstes Element in gleicher Hierachieebene (NULL, wenn letzer Eintrag)
+ u_int32_t TreeValue; // Anteil an Suchbegriff
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: struct TreeEndNode
+ Conv: PortNetScan
+ Typ: verkettete Liste
+ Info: für Einträge Zieladressen oder Zielports ind TreeEndNode
+*/
+struct TreeEndNodeEntry
+{
+ //Public Vars
+ u_int32_t Value;
+ struct TreeEndNodeEntry * Next;
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: struct TreeEndNode
+ Conv: PortNetScan
+ Typ: verkettete Liste mit Verweis auf Suchbaum (Parent)
+ Info: Überwachte Einträge mit angehängten verketteten Listen
+ für Zieladressen und Zielports. Zusätzlich werden
+ Zähler für Zugriff, Zieladressen und Zielports gespeichert.
+*/
+struct TreeEndNode
+{
+ //Public Vars
+ struct TreeNode * Parent; // letzte Treenode in der Such-Hierachie
+ time_t FirstTime; // Erstes Auftreten
+ time_t LastTime; // Letze Erfassung
+ IpV4Address Src; // Quelladresse
+ u_int32_t Count; // Anzahl Pakete seit ersten Erfassen
+ u_int32_t CountDpt; // Anzahl Ziel-Ports
+ u_int32_t CountDst; // Anzahl Ziel-Adressen
+ struct TreeEndNodeEntry * EntriesDst; // Einträge Zieladressen (Verweis auf eine verkettete Listen NULL wenn keine definiert wurde)
+ struct TreeEndNodeEntry * EntriesDpt; // Einträge Zielports (Verweis auf eine verkettete Listen NULL wenn keine definiert wurde)
+ struct TreeEndNode * Next; // Nächster Eintrag in verketteter Liste ( NULL wenn letzter Eintrag)
+ struct TreeEndNode * Prior; // Vorheriger Eintrag in verketteter Liste ( NULL wenn erster Eintrag)
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: struct DenyList
+ Conv: PortNetScan
+ Typ: verkettete Liste
+ Info: Gesperrte Einträge einer Konfigurationsumgebung
+*/
+struct DenyList
+{
+ IpV4Address Src; // Quelladresse
+ time_t StartDenyTime; // Unix-Zeit, an welcher die Quelladresse gesperrt wurde
+ u_int32_t Count; // Versuchte Zugriffe seit Sperrung
+ unsigned int Reason; // Grund für Sperrung ( Aktuell: REASONPORTSCAN, REASONNETSCAN, REASONCOMPINED, REASONUNKNOWN)
+ struct DenyList * Next; // Nächster Eintrag in verketteter Liste ( NULL wenn letzter Eintrag)
+ struct DenyList * Prior; // Vorheriger Eintrag in verketteter Liste ( NULL wenn erster Eintrag)
+};
+
+
+/*
+ Init Funktionen sind Functionen, die nach dem
+ Allokieren (malloc/kalloc) ausgeführt werden sollte,
+ um alle verwendeten Variablen eines structs / virtuellen Klassen
+ auf Standardwerten zu setzen
+
+ Die Funktionen sind soweit notwendig in der ipt_PORTNETSCAN.c inline dokumentiert.
+*/
+// Supportfunctions
+unsigned int powpos ( unsigned short A, unsigned short B );
+time_t getunixtime(void);
+// Functions virt. Namespace PortNetscan
+void PortNetscan_Init(struct PortNetscanConf * ENV);
+void PortNetscan_Flush(struct PortNetscanConf * ENV);
+void DenyList_Init(struct PortNetscanConf * ENV,struct DenyList*);
+void DenyList_Flush(struct PortNetscanConf * ENV,struct DenyList*);
+void TreeEndNode_Init(struct PortNetscanConf * ENV,struct TreeEndNode*);
+void TreeEndNode_Flush(struct PortNetscanConf * ENV,struct TreeEndNode*);
+void TreeEndNodeEntry_Init(struct PortNetscanConf * ENV,struct TreeEndNodeEntry*);
+void TreeEndNodeEntry_Flush(struct PortNetscanConf * ENV,struct TreeEndNodeEntry*);
+void TreeNode_Init(struct PortNetscanConf * ENV,struct TreeNode*);
+void TreeNode_Flush(struct PortNetscanConf * ENV,struct TreeNode*);
+// Functions
+void PortNetscan_Cleanup(struct PortNetscanConf * ENV);
+void PortNetscan_CleanupAll(struct PortNetscanConf * ENV);
+int PortNetscan_Check(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT, unsigned short OnlyCheckDeny);
+int PortNetscan_SetTreeDepth(struct PortNetscanConf * ENV,const unsigned short DEPTH);
+int PortNetscan_SetTraceTime(struct PortNetscanConf * ENV,const unsigned int TRACETIME);
+int PortNetscan_SetCleanInterval(struct PortNetscanConf * ENV,const unsigned int CLEANINTERVAL);
+int PortNetscan_SetPortscanQuota(struct PortNetscanConf * ENV,const unsigned int PORTSCANQUOTA);
+int PortNetscan_SetNetscanQuota(struct PortNetscanConf * ENV,const unsigned int NETSCANQUOTA);
+int PortNetscan_SetBlockTime(struct PortNetscanConf * ENV,const unsigned int BLOCKTIME);
+int PortNetscan_SetMaxDenyListCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE);
+int PortNetscan_SetNodeCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE);
+// Private Functions
+/*
+ Private Functions
+ Diese Funktionen sollten in keinem Fall direkt im Hauptprogramm angesprochen werden. Diese
+ Funktionen dienen nur für andere Funktionen, um interne Aktionen auszuführen.
+*/
+int PortNetscan_Add(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT);
+struct TreeNode * PortNetscan_AddTree(struct PortNetscanConf * ENV,struct TreeNode * TREENODE,const u_int32_t * IPPARTS,const unsigned short DEPTH);
+struct TreeEndNode * PortNetscan_AddTreeEndNode(struct PortNetscanConf * ENV,struct TreeNode * LastTreeNode, IpV4Address SRC, IpV4Address DST, IpV4Port DPT );
+int PortNetscan_GetIpV4Parts(struct PortNetscanConf * ENV,const u_int32_t IPV4ADDR,u_int32_t * IPPARTS);
+int PortNetscan_AddEndTreeEnty(struct PortNetscanConf * ENV,struct TreeEndNodeEntry * ENTRY, const u_int32_t VALUE);
+int PortNetscan_DelTreeEndNode(struct PortNetscanConf * ENV,struct TreeEndNode * ENTRY);
+int PortNetscan_DelTreeUnuses(struct PortNetscanConf * ENV,struct TreeNode *TREENODE);
+struct DenyList * PortNetscan_AddDenyListEntry(struct PortNetscanConf * ENV,const IpV4Address SRC);
+int PortNetscan_DelDenyListEntry(struct PortNetscanConf * ENV,struct DenyList * ENTRY);
+int PortNetscan_CheckDenyList(struct PortNetscanConf * ENV,const IpV4Address SRC);
+
+
+
+#ifdef __KERNEL__
+// Kernel Static Structs
+static struct timer_list Kernel_CleanupTimer;
+// Kernel- and Modulfunctions
+void Kernel_CleanupAll(unsigned long FORCE);
+void Kernel_CreateProcEnv(void);
+void Kernel_DeleteProcEnv(void);
+int Kernel_WriteOutLinePufferToProc(char * BUFFER,int COUNT);
+int Kernel_ReadProcmem(char * BUFFER, char ** START, off_t OFFSET, int COUNT, int *EOF, void * DATA);
+int Kernel_FlushProcmemPuffer(void);
+int Kernel_CreateProcmemPuffer(void);
+int Kernel_CreateProcmemPufferAddEntry(char * LINE);
+#endif
+
+
+// End Global Defs
+#endif
+
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig linux-2.6.20.2/net/ipv4/netfilter/Kconfig
--- linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig 2007-03-09 19:58:04.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Kconfig 2007-03-10 14:33:15.000000000 +0100
@@ -312,6 +312,16 @@
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
+config IP_NF_MATCH_PORTNETSCAN
+ tristate 'portnetscan detection match support'
+ depends on IP_NF_IPTABLES
+ help
+ PORTNETSCAN is an iptables module for the detection of PORT-, NET
+ and COMBINEDSCANS using quotas. The usage is described in the
+ accompanying document located at Documentation/ipt_PORTNETSCAN.txt
+
+ To compile it as a module, choose M here. If unsure, say N.
+
# `filter', generic and specific targets
config IP_NF_FILTER
tristate "Packet filtering"
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig.orig linux-2.6.20.2/net/ipv4/netfilter/Kconfig.orig
--- linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Kconfig.orig 2007-03-09 19:58:04.000000000 +0100
@@ -0,0 +1,685 @@
+#
+# IP netfilter configuration
+#
+
+menu "IP: Netfilter Configuration"
+ depends on INET && NETFILTER
+
+config NF_CONNTRACK_IPV4
+ tristate "IPv4 connection tracking support (required for NAT)"
+ depends on NF_CONNTRACK
+ ---help---
+ Connection tracking keeps a record of what packets have passed
+ through your machine, in order to figure out how they are related
+ into connections.
+
+ This is IPv4 support on Layer 3 independent connection tracking.
+ Layer 3 independent connection tracking is experimental scheme
+ which generalize ip_conntrack to support other layer 3 protocols.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config NF_CONNTRACK_PROC_COMPAT
+ bool "proc/sysctl compatibility with old connection tracking"
+ depends on NF_CONNTRACK_IPV4
+ default y
+ help
+ This option enables /proc and sysctl compatibility with the old
+ layer 3 dependant connection tracking. This is needed to keep
+ old programs that have not been adapted to the new names working.
+
+ If unsure, say Y.
+
+# connection tracking, helpers and protocols
+config IP_NF_CT_ACCT
+ bool "Connection tracking flow accounting"
+ depends on IP_NF_CONNTRACK
+ help
+ If this option is enabled, the connection tracking code will
+ keep per-flow packet and byte counters.
+
+ Those counters can be used for flow-based accounting or the
+ `connbytes' match.
+
+ If unsure, say `N'.
+
+config IP_NF_CONNTRACK_MARK
+ bool 'Connection mark tracking support'
+ depends on IP_NF_CONNTRACK
+ help
+ This option enables support for connection marks, used by the
+ `CONNMARK' target and `connmark' match. Similar to the mark value
+ of packets, but this mark value is kept in the conntrack session
+ instead of the individual packets.
+
+config IP_NF_CONNTRACK_SECMARK
+ bool 'Connection tracking security mark support'
+ depends on IP_NF_CONNTRACK && NETWORK_SECMARK
+ help
+ This option enables security markings to be applied to
+ connections. Typically they are copied to connections from
+ packets using the CONNSECMARK target and copied back from
+ connections to packets with the same target, with the packets
+ being originally labeled via SECMARK.
+
+ If unsure, say 'N'.
+
+config IP_NF_CONNTRACK_EVENTS
+ bool "Connection tracking events (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && IP_NF_CONNTRACK
+ help
+ If this option is enabled, the connection tracking code will
+ provide a notifier chain that can be used by other kernel code
+ to get notified about changes in the connection tracking state.
+
+ IF unsure, say `N'.
+
+config IP_NF_CONNTRACK_NETLINK
+ tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
+ depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK
+ depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
+ depends on IP_NF_NAT=n || IP_NF_NAT
+ help
+ This option enables support for a netlink-based userspace interface
+
+
+config IP_NF_CT_PROTO_SCTP
+ tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
+ depends on IP_NF_CONNTRACK && EXPERIMENTAL
+ help
+ With this option enabled, the connection tracking code will
+ be able to do state tracking on SCTP connections.
+
+ If you want to compile it as a module, say M here and read
+ <file:Documentation/modules.txt>. If unsure, say `N'.
+
+config IP_NF_FTP
+ tristate "FTP protocol support"
+ depends on IP_NF_CONNTRACK
+ help
+ Tracking FTP connections is problematic: special helpers are
+ required for tracking them, and doing masquerading and other forms
+ of Network Address Translation on them.
+
+ To compile it as a module, choose M here. If unsure, say Y.
+
+config IP_NF_IRC
+ tristate "IRC protocol support"
+ depends on IP_NF_CONNTRACK
+ ---help---
+ There is a commonly-used extension to IRC called
+ Direct Client-to-Client Protocol (DCC). This enables users to send
+ files to each other, and also chat to each other without the need
+ of a server. DCC Sending is used anywhere you send files over IRC,
+ and DCC Chat is most commonly used by Eggdrop bots. If you are
+ using NAT, this extension will enable you to send files and initiate
+ chats. Note that you do NOT need this extension to get files or
+ have others initiate chats, or everything else in IRC.
+
+ To compile it as a module, choose M here. If unsure, say Y.
+
+config IP_NF_NETBIOS_NS
+ tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
+ depends on IP_NF_CONNTRACK && EXPERIMENTAL
+ help
+ NetBIOS name service requests are sent as broadcast messages from an
+ unprivileged port and responded to with unicast messages to the
+ same port. This make them hard to firewall properly because connection
+ tracking doesn't deal with broadcasts. This helper tracks locally
+ originating NetBIOS name service requests and the corresponding
+ responses. It relies on correct IP address configuration, specifically
+ netmask and broadcast address. When properly configured, the output
+ of "ip address show" should look similar to this:
+
+ $ ip -4 address show eth0
+ 4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
+ inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TFTP
+ tristate "TFTP protocol support"
+ depends on IP_NF_CONNTRACK
+ help
+ TFTP connection tracking helper, this is required depending
+ on how restrictive your ruleset is.
+ If you are using a tftp client behind -j SNAT or -j MASQUERADING
+ you will need this.
+
+ To compile it as a module, choose M here. If unsure, say Y.
+
+config IP_NF_AMANDA
+ tristate "Amanda backup protocol support"
+ depends on IP_NF_CONNTRACK
+ select TEXTSEARCH
+ select TEXTSEARCH_KMP
+ help
+ If you are running the Amanda backup package <http://www.amanda.org/>
+ on this machine or machines that will be MASQUERADED through this
+ machine, then you may want to enable this feature. This allows the
+ connection tracking and natting code to allow the sub-channels that
+ Amanda requires for communication of the backup data, messages and
+ index.
+
+ To compile it as a module, choose M here. If unsure, say Y.
+
+config IP_NF_PPTP
+ tristate 'PPTP protocol support'
+ depends on IP_NF_CONNTRACK
+ help
+ This module adds support for PPTP (Point to Point Tunnelling
+ Protocol, RFC2637) connection tracking and NAT.
+
+ If you are running PPTP sessions over a stateful firewall or NAT
+ box, you may want to enable this feature.
+
+ Please note that not all PPTP modes of operation are supported yet.
+ For more info, read top of the file
+ net/ipv4/netfilter/ip_conntrack_pptp.c
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
+
+config IP_NF_H323
+ tristate 'H.323 protocol support (EXPERIMENTAL)'
+ depends on IP_NF_CONNTRACK && EXPERIMENTAL
+ help
+ H.323 is a VoIP signalling protocol from ITU-T. As one of the most
+ important VoIP protocols, it is widely used by voice hardware and
+ software including voice gateways, IP phones, Netmeeting, OpenPhone,
+ Gnomemeeting, etc.
+
+ With this module you can support H.323 on a connection tracking/NAT
+ firewall.
+
+ This module supports RAS, Fast Start, H.245 Tunnelling, Call
+ Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat,
+ whiteboard, file transfer, etc. For more information, please
+ visit http://nath323.sourceforge.net/.
+
+ If you want to compile it as a module, say 'M' here and read
+ Documentation/modules.txt. If unsure, say 'N'.
+
+config IP_NF_SIP
+ tristate "SIP protocol support (EXPERIMENTAL)"
+ depends on IP_NF_CONNTRACK && EXPERIMENTAL
+ help
+ SIP is an application-layer control protocol that can establish,
+ modify, and terminate multimedia sessions (conferences) such as
+ Internet telephony calls. With the ip_conntrack_sip and
+ the ip_nat_sip modules you can support the protocol on a connection
+ tracking/NATing firewall.
+
+ To compile it as a module, choose M here. If unsure, say Y.
+
+config IP_NF_QUEUE
+ tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
+ help
+ Netfilter has the ability to queue packets to user space: the
+ netlink device can be used to access them using this driver.
+
+ This option enables the old IPv4-only "ip_queue" implementation
+ which has been obsoleted by the new "nfnetlink_queue" code (see
+ CONFIG_NETFILTER_NETLINK_QUEUE).
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_IPTABLES
+ tristate "IP tables support (required for filtering/masq/NAT)"
+ depends on NETFILTER_XTABLES
+ help
+ iptables is a general, extensible packet identification framework.
+ The packet filtering and full NAT (masquerading, port forwarding,
+ etc) subsystems now use this: say `Y' or `M' here if you want to use
+ either of those.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+# The matches.
+config IP_NF_MATCH_IPRANGE
+ tristate "IP range match support"
+ depends on IP_NF_IPTABLES
+ help
+ This option makes possible to match IP addresses against IP address
+ ranges.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_MATCH_TOS
+ tristate "TOS match support"
+ depends on IP_NF_IPTABLES
+ help
+ TOS matching allows you to match packets based on the Type Of
+ Service fields of the IP packet.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_MATCH_RECENT
+ tristate "recent match support"
+ depends on IP_NF_IPTABLES
+ help
+ This match is used for creating one or many lists of recently
+ used addresses and then matching against that/those list(s).
+
+ Short options are available by using 'iptables -m recent -h'
+ Official Website: <http://snowman.net/projects/ipt_recent/>
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_MATCH_ECN
+ tristate "ECN match support"
+ depends on IP_NF_IPTABLES
+ help
+ This option adds a `ECN' match, which allows you to match against
+ the IPv4 and TCP header ECN fields.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_MATCH_AH
+ tristate "AH match support"
+ depends on IP_NF_IPTABLES
+ help
+ This match extension allows you to match a range of SPIs
+ inside AH header of IPSec packets.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_MATCH_TTL
+ tristate "TTL match support"
+ depends on IP_NF_IPTABLES
+ help
+ This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
+ to match packets by their TTL value.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_MATCH_OWNER
+ tristate "Owner match support"
+ depends on IP_NF_IPTABLES
+ help
+ Packet owner matching allows you to match locally-generated packets
+ based on who created them: the user, group, process or session.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_MATCH_ADDRTYPE
+ tristate 'address type match support'
+ depends on IP_NF_IPTABLES
+ help
+ This option allows you to match what routing thinks of an address,
+ eg. UNICAST, LOCAL, BROADCAST, ...
+
+ If you want to compile it as a module, say M here and read
+ <file:Documentation/modules.txt>. If unsure, say `N'.
+
+# `filter', generic and specific targets
+config IP_NF_FILTER
+ tristate "Packet filtering"
+ depends on IP_NF_IPTABLES
+ help
+ Packet filtering defines a table `filter', which has a series of
+ rules for simple packet filtering at local input, forwarding and
+ local output. See the man page for iptables(8).
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_REJECT
+ tristate "REJECT target support"
+ depends on IP_NF_FILTER
+ help
+ The REJECT target allows a filtering rule to specify that an ICMP
+ error should be issued in response to an incoming packet, rather
+ than silently being dropped.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_LOG
+ tristate "LOG target support"
+ depends on IP_NF_IPTABLES
+ help
+ This option adds a `LOG' target, which allows you to create rules in
+ any iptables table which records the packet header to the syslog.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_ULOG
+ tristate "ULOG target support"
+ depends on IP_NF_IPTABLES
+ ---help---
+
+ This option enables the old IPv4-only "ipt_ULOG" implementation
+ which has been obsoleted by the new "nfnetlink_log" code (see
+ CONFIG_NETFILTER_NETLINK_LOG).
+
+ This option adds a `ULOG' target, which allows you to create rules in
+ any iptables table. The packet is passed to a userspace logging
+ daemon using netlink multicast sockets; unlike the LOG target
+ which can only be viewed through syslog.
+
+ The appropriate userspace logging daemon (ulogd) may be obtained from
+ <http://www.gnumonks.org/projects/ulogd/>
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_TCPMSS
+ tristate "TCPMSS target support"
+ depends on IP_NF_IPTABLES
+ ---help---
+ This option adds a `TCPMSS' target, which allows you to alter the
+ MSS value of TCP SYN packets, to control the maximum size for that
+ connection (usually limiting it to your outgoing interface's MTU
+ minus 40).
+
+ This is used to overcome criminally braindead ISPs or servers which
+ block ICMP Fragmentation Needed packets. The symptoms of this
+ problem are that everything works fine from your Linux
+ firewall/router, but machines behind it can never exchange large
+ packets:
+ 1) Web browsers connect, then hang with no data received.
+ 2) Small mail works fine, but large emails hang.
+ 3) ssh works fine, but scp hangs after initial handshaking.
+
+ Workaround: activate this option and add a rule to your firewall
+ configuration like:
+
+ iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
+ -j TCPMSS --clamp-mss-to-pmtu
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+# NAT + specific targets: ip_conntrack
+config IP_NF_NAT
+ tristate "Full NAT"
+ depends on IP_NF_IPTABLES && IP_NF_CONNTRACK
+ help
+ The Full NAT option allows masquerading, port forwarding and other
+ forms of full Network Address Port Translation. It is controlled by
+ the `nat' table in iptables: see the man page for iptables(8).
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+# NAT + specific targets: nf_conntrack
+config NF_NAT
+ tristate "Full NAT"
+ depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4
+ help
+ The Full NAT option allows masquerading, port forwarding and other
+ forms of full Network Address Port Translation. It is controlled by
+ the `nat' table in iptables: see the man page for iptables(8).
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_NAT_NEEDED
+ bool
+ depends on IP_NF_NAT
+ default y
+
+config NF_NAT_NEEDED
+ bool
+ depends on NF_NAT
+ default y
+
+config IP_NF_TARGET_MASQUERADE
+ tristate "MASQUERADE target support"
+ depends on (NF_NAT || IP_NF_NAT)
+ help
+ Masquerading is a special case of NAT: all outgoing connections are
+ changed to seem to come from a particular interface's address, and
+ if the interface goes down, those connections are lost. This is
+ only useful for dialup accounts with dynamic IP address (ie. your IP
+ address will be different on next dialup).
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_REDIRECT
+ tristate "REDIRECT target support"
+ depends on (NF_NAT || IP_NF_NAT)
+ help
+ REDIRECT is a special case of NAT: all incoming connections are
+ mapped onto the incoming interface's address, causing the packets to
+ come to the local machine instead of passing through. This is
+ useful for transparent proxies.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_NETMAP
+ tristate "NETMAP target support"
+ depends on (NF_NAT || IP_NF_NAT)
+ help
+ NETMAP is an implementation of static 1:1 NAT mapping of network
+ addresses. It maps the network address part, while keeping the host
+ address part intact. It is similar to Fast NAT, except that
+ Netfilter's connection tracking doesn't work well with Fast NAT.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_SAME
+ tristate "SAME target support"
+ depends on (NF_NAT || IP_NF_NAT)
+ help
+ This option adds a `SAME' target, which works like the standard SNAT
+ target, but attempts to give clients the same IP for all connections.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_NAT_SNMP_BASIC
+ tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && IP_NF_NAT
+ ---help---
+
+ This module implements an Application Layer Gateway (ALG) for
+ SNMP payloads. In conjunction with NAT, it allows a network
+ management system to access multiple private networks with
+ conflicting addresses. It works by modifying IP addresses
+ inside SNMP payloads to match IP-layer NAT mapping.
+
+ This is the "basic" form of SNMP-ALG, as described in RFC 2962
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config NF_NAT_SNMP_BASIC
+ tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && NF_NAT
+ ---help---
+
+ This module implements an Application Layer Gateway (ALG) for
+ SNMP payloads. In conjunction with NAT, it allows a network
+ management system to access multiple private networks with
+ conflicting addresses. It works by modifying IP addresses
+ inside SNMP payloads to match IP-layer NAT mapping.
+
+ This is the "basic" form of SNMP-ALG, as described in RFC 2962
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+# If they want FTP, set to $CONFIG_IP_NF_NAT (m or y),
+# or $CONFIG_IP_NF_FTP (m or y), whichever is weaker.
+# From kconfig-language.txt:
+#
+# <expr> '&&' <expr> (6)
+#
+# (6) Returns the result of min(/expr/, /expr/).
+config NF_NAT_PROTO_GRE
+ tristate
+ depends on NF_NAT && NF_CT_PROTO_GRE
+
+config IP_NF_NAT_FTP
+ tristate
+ depends on IP_NF_IPTABLES && IP_NF_CONNTRACK && IP_NF_NAT
+ default IP_NF_NAT && IP_NF_FTP
+
+config NF_NAT_FTP
+ tristate
+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ default NF_NAT && NF_CONNTRACK_FTP
+
+config IP_NF_NAT_IRC
+ tristate
+ depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+ default IP_NF_NAT if IP_NF_IRC=y
+ default m if IP_NF_IRC=m
+
+config NF_NAT_IRC
+ tristate
+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ default NF_NAT && NF_CONNTRACK_IRC
+
+config IP_NF_NAT_TFTP
+ tristate
+ depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+ default IP_NF_NAT if IP_NF_TFTP=y
+ default m if IP_NF_TFTP=m
+
+config NF_NAT_TFTP
+ tristate
+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ default NF_NAT && NF_CONNTRACK_TFTP
+
+config IP_NF_NAT_AMANDA
+ tristate
+ depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+ default IP_NF_NAT if IP_NF_AMANDA=y
+ default m if IP_NF_AMANDA=m
+
+config NF_NAT_AMANDA
+ tristate
+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ default NF_NAT && NF_CONNTRACK_AMANDA
+
+config IP_NF_NAT_PPTP
+ tristate
+ depends on IP_NF_NAT!=n && IP_NF_PPTP!=n
+ default IP_NF_NAT if IP_NF_PPTP=y
+ default m if IP_NF_PPTP=m
+
+config NF_NAT_PPTP
+ tristate
+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ default NF_NAT && NF_CONNTRACK_PPTP
+ select NF_NAT_PROTO_GRE
+
+config IP_NF_NAT_H323
+ tristate
+ depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+ default IP_NF_NAT if IP_NF_H323=y
+ default m if IP_NF_H323=m
+
+config NF_NAT_H323
+ tristate
+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ default NF_NAT && NF_CONNTRACK_H323
+
+config IP_NF_NAT_SIP
+ tristate
+ depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+ default IP_NF_NAT if IP_NF_SIP=y
+ default m if IP_NF_SIP=m
+
+config NF_NAT_SIP
+ tristate
+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+ default NF_NAT && NF_CONNTRACK_SIP
+
+# mangle + specific targets
+config IP_NF_MANGLE
+ tristate "Packet mangling"
+ depends on IP_NF_IPTABLES
+ help
+ This option adds a `mangle' table to iptables: see the man page for
+ iptables(8). This table is used for various packet alterations
+ which can effect how the packet is routed.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_TOS
+ tristate "TOS target support"
+ depends on IP_NF_MANGLE
+ help
+ This option adds a `TOS' target, which allows you to create rules in
+ the `mangle' table which alter the Type Of Service field of an IP
+ packet prior to routing.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_ECN
+ tristate "ECN target support"
+ depends on IP_NF_MANGLE
+ ---help---
+ This option adds a `ECN' target, which can be used in the iptables mangle
+ table.
+
+ You can use this target to remove the ECN bits from the IPv4 header of
+ an IP packet. This is particularly useful, if you need to work around
+ existing ECN blackholes on the internet, but don't want to disable
+ ECN support in general.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_TTL
+ tristate 'TTL target support'
+ depends on IP_NF_MANGLE
+ help
+ This option adds a `TTL' target, which enables the user to modify
+ the TTL value of the IP header.
+
+ While it is safe to decrement/lower the TTL, this target also enables
+ functionality to increment and set the TTL value of the IP header to
+ arbitrary values. This is EXTREMELY DANGEROUS since you can easily
+ create immortal packets that loop forever on the network.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_TARGET_CLUSTERIP
+ tristate "CLUSTERIP target support (EXPERIMENTAL)"
+ depends on IP_NF_MANGLE && EXPERIMENTAL
+ depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
+ help
+ The CLUSTERIP target allows you to build load-balancing clusters of
+ network servers without having a dedicated load-balancing
+ router/server/switch.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+# raw + specific targets
+config IP_NF_RAW
+ tristate 'raw table support (required for NOTRACK/TRACE)'
+ depends on IP_NF_IPTABLES
+ help
+ This option adds a `raw' table to iptables. This table is the very
+ first in the netfilter framework and hooks in at the PREROUTING
+ and OUTPUT chains.
+
+ If you want to compile it as a module, say M here and read
+ <file:Documentation/modules.txt>. If unsure, say `N'.
+
+# ARP tables
+config IP_NF_ARPTABLES
+ tristate "ARP tables support"
+ depends on NETFILTER_XTABLES
+ help
+ arptables is a general, extensible packet identification framework.
+ The ARP packet filtering and mangling (manipulation)subsystems
+ use this: say Y or M here if you want to use either of those.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_ARPFILTER
+ tristate "ARP packet filtering"
+ depends on IP_NF_ARPTABLES
+ help
+ ARP packet filtering defines a table `filter', which has a series of
+ rules for simple ARP packet filtering at local input and
+ local output. On a bridge, you can also specify filtering rules
+ for forwarded ARP packets. See the man page for arptables(8).
+
+ To compile it as a module, choose M here. If unsure, say N.
+
+config IP_NF_ARP_MANGLE
+ tristate "ARP payload mangling"
+ depends on IP_NF_ARPTABLES
+ help
+ Allows altering the ARP packet payload: source and destination
+ hardware and network addresses.
+
+endmenu
+
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Makefile linux-2.6.20.2/net/ipv4/netfilter/Makefile
--- linux-2.6.20.2.org/net/ipv4/netfilter/Makefile 2007-03-09 19:58:04.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Makefile 2007-03-10 14:33:15.000000000 +0100
@@ -91,6 +91,7 @@
obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
+obj-$(CONFIG_IP_NF_MATCH_PORTNETSCAN) += ipt_PORTNETSCAN.o
# targets
obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Makefile.orig linux-2.6.20.2/net/ipv4/netfilter/Makefile.orig
--- linux-2.6.20.2.org/net/ipv4/netfilter/Makefile.orig 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Makefile.orig 2007-03-09 19:58:04.000000000 +0100
@@ -0,0 +1,118 @@
+#
+# Makefile for the netfilter modules on top of IPv4.
+#
+
+# objects for the standalone - connection tracking / NAT
+ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
+# objects for l3 independent conntrack
+nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
+ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y)
+ifeq ($(CONFIG_PROC_FS),y)
+nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
+endif
+endif
+
+ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
+nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
+ifneq ($(CONFIG_NF_NAT),)
+iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o
+else
+iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o
+endif
+
+ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
+ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o
+
+ip_conntrack_h323-objs := ip_conntrack_helper_h323.o ../../netfilter/nf_conntrack_h323_asn1.o
+ip_nat_h323-objs := ip_nat_helper_h323.o
+
+# connection tracking
+obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
+obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
+
+obj-$(CONFIG_IP_NF_NAT) += ip_nat.o
+obj-$(CONFIG_NF_NAT) += nf_nat.o
+
+# conntrack netlink interface
+obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
+
+
+# SCTP protocol connection tracking
+obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
+
+# connection tracking helpers
+obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
+obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o
+obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
+obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
+obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
+obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
+obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o
+obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
+
+# NAT helpers (ip_conntrack)
+obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
+obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
+obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
+obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
+obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
+obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
+obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
+
+# NAT helpers (nf_conntrack)
+obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
+obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
+obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
+obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o
+obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
+obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o
+obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
+obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
+
+# NAT protocols (nf_nat)
+obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
+
+# generic IP tables
+obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
+
+# the three instances of ip_tables
+obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
+obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
+obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
+obj-$(CONFIG_NF_NAT) += iptable_nat.o
+obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
+
+# matches
+obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
+obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
+obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
+obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
+obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
+obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
+
+# targets
+obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
+obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
+obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
+obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
+obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
+obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
+obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
+obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
+obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
+obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
+obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
+obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
+obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
+
+# generic ARP tables
+obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
+obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
+
+# just filtering instance of ARP tables for now
+obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
+
+obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
+
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/ipt_PORTNETSCAN.c linux-2.6.20.2/net/ipv4/netfilter/ipt_PORTNETSCAN.c
--- linux-2.6.20.2.org/net/ipv4/netfilter/ipt_PORTNETSCAN.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/ipt_PORTNETSCAN.c 2007-03-10 14:54:55.000000000 +0100
@@ -0,0 +1,2227 @@
+/*
+ Name: ipt_PORTNETSCAN.c
+ Date: 16.05.2006
+ Last change: 03.03.2007
+ Version: 0.3
+
+ Bemerkung:
+ Detect port- or netscans
+
+ Copyright (C) Robert Gladewitz
+ Fachhochschule Heidelberg
+
+ This file is distributed under the terms of the GNU General Public
+ License (GPL). Copies of the GPL can be obtained from:
+ http://www.gnu.org/licenses/gpl.html
+
+ 2006-05-26 Robert Gladewitz <gladewitz@gmx.de> : initial
+ 2006-05-30 Robert Gladewitz <gladewitz@gmx.de> : start testingseries in simulations networks in different situations
+ 2006-06-05 Robert Gladewitz <gladewitz@gmx.de> : adding --check-deny-enttries
+ 2006-06-22 Robert Gladewitz <gladewitz@gmx.de> : fix bug: no deleting emty conft-entries (LastUse)
+ 2006-07-06 Robert Gladewitz <gladewitz@gmx.de> : Support for new structure for iptables in kernel 2.6.17
+ 2006-08-03 Robert Gladewitz <gladewitz@gmx.de> : Correct wrong parameter deep to depth (misunderstanding parameter deep)
+ 2007-03-03 Robert Gladewitz <gladewitz@gmx.de> : Change some structures and documentations
+*/
+
+/*
+######################################################################################################################
+#### Includes ########################################################################################################
+######################################################################################################################
+*/
+
+#define _debug printk
+
+#ifdef __KERNEL__
+
+#include <linux/time.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/tcp.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <net/dst.h>
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_PORTNETSCAN.h>
+
+
+// Maybe for later functions, now here tcp and udp implemented
+//#include <linux/icmp.h>
+//#include <net/icmp.h>
+//#include <net/route.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Gladewitz <gladewitz@gmx.de>");
+MODULE_DESCRIPTION("port- and netscan detection");
+
+#else
+
+// Testing
+#include <stdio.h> // Standard IO functions
+#include <stdlib.h> // Standard LIB functions
+#include <time.h> // Zeittypen - time functions
+
+#include "PortNetscan.h"
+
+#endif
+
+
+
+/*
+#######################################################################################################################
+#### Nich vorhandene Funktionen ersetzen ##############################################################################
+#######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: powpos
+ Conv: Support Kernel
+ Typ: function
+ return: unsigned int ( Ergebnis A hoch B )
+ Par 1: unsigned short A
+ Par 2: unsigned short B
+ Info: Die Funktion errechnet A hoch B
+*/
+unsigned int powpos ( unsigned short A, unsigned short B )
+{
+ u_int32_t RC = 0;
+ if ( B == 0 )
+ {
+ RC = 1;
+ }
+ else if ( A == 0 )
+ {
+ RC = 0;
+ }
+ else
+ {
+ unsigned int I;
+ RC=A;
+ for (I=1; I<B; I++) RC = RC * A;
+ }
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: getunixtime
+ Conv: Support Kernel
+ Typ: function
+ return: time_t
+ Par 1: void (Keine übergebenen Parameter)
+ Info: Diese Funktion gibt die aktuelle Unix-Zeit zurück (nur Sekunden seit Start der Unix-Zeit)
+*/
+time_t getunixtime(void)
+{
+ /*
+ Leider werden die Funktionen der time.h nicht unterstützt - hier eine eigene
+ Imlementierung der Funtionen time(0).
+ */
+ // Functionsvariablen
+ time_t RC = 0;
+#ifdef __KERNEL__
+ struct timeval TEMPTIMEVAL;
+ do_gettimeofday(&TEMPTIMEVAL);
+ RC = TEMPTIMEVAL.tv_sec;
+#else
+ RC = time(0);
+#endif
+ return RC;
+}
+
+/*
+######################################################################################################################
+#### TreeNode ########################################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: TreeNode_Init
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+ Par 2: struct TreeNode ( Zu initialisierender struct TreeNode)
+ Info: Diese Funktion initialsiert alle Inhalte des übergebenen Strukts TreeNode mit den Standardwerten. Diese
+ Funktion sollte nach jedem malloc-Aufruf einer neuen TreeNode ausgeführt werden.
+*/
+void TreeNode_Init(struct PortNetscanConf * ENV,struct TreeNode* V)
+{
+ // Alle Zeigervariablen mit NULL initialisieren
+ V->Parent = NULL;
+ V->Prior = NULL;
+ V->Next = NULL;
+ V->Childs = NULL;
+ V->TreeValue = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: TreeNode_Flush
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2:
+ Info:
+*/
+void TreeNode_Flush(struct PortNetscanConf * ENV,struct TreeNode* V)
+{
+ // Alle Zeigervariablen mit NULL initialisieren
+ V->Parent = NULL;
+ V->Prior = NULL;
+ V->Next = NULL;
+ V->Childs = NULL;
+ V->TreeValue = 0;
+}
+/*
+######################################################################################################################
+#### Class: TreeEndNodeEntry #########################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: TreeEndNodeEntry_Init
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+ Par 2: struct TreeEndNodeEntry ( Zu initialisierender struct TreeEndNodeEndtry)
+ Info: Diese Funktion initialsiert alle Inhalte des übergebenen Strukts TreeEndNodeEntry mit den Standardwerten. Diese
+ Funktion sollte nach jedem malloc-Aufruf einer neuen TreeEndNodeEntry ausgeführt werden.
+*/
+void TreeEndNodeEntry_Init(struct PortNetscanConf * ENV,struct TreeEndNodeEntry* V)
+{
+ V->Next = NULL;
+ V->Value = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: TreeEndNodeEntry_Flush
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: TreeEndNodeEntry
+ Info: Zurücksetzen der Variablen fpr TreeEndNode auf die Standardwerte
+*/
+void TreeEndNodeEntry_Flush(struct PortNetscanConf * ENV,struct TreeEndNodeEntry* V)
+{
+ V->Next = NULL;
+ V->Value = 0;
+}
+/*
+######################################################################################################################
+#### Class: TreeEndNode ##############################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: TreeEndNode_Init
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+ Par 2: struct TreeEndNode ( Zu initialisierender struct TreeNode)
+ Info: Diese Funktion initialsiert alle Inahlte des übergebenen Strukts TreeEndNode mit den Standardwerten. Diese
+ Funktion sollte nach jedem malloc-Aufruf einer neuen TreeEndNode ausgeführt werden.
+*/
+void TreeEndNode_Init(struct PortNetscanConf * ENV,struct TreeEndNode* V)
+{
+ // Alle Zeigervariablen mit NULL initialisieren
+ V->EntriesDst = NULL;
+ V->EntriesDpt = NULL;
+ V->Parent = NULL;
+ V->Next = NULL;
+ V->Prior = NULL;
+ V->Count = 0;
+ V->CountDst = 0;
+ V->CountDpt = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: TreeEndNode_Flush
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2:
+ Info:
+*/
+void TreeEndNode_Flush(struct PortNetscanConf * ENV,struct TreeEndNode* V)
+{
+ V->EntriesDst = NULL;
+ V->EntriesDpt = NULL;
+ V->Parent = NULL;
+ V->Next = NULL;
+ V->Prior = NULL;
+ V->Count = 0;
+ V->CountDst = 0;
+ V->CountDpt = 0;
+ V->FirstTime = 0;
+ V->LastTime = 0;
+}
+/*
+######################################################################################################################
+#### Class: PortNetscanDenyList ######################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: DenyList_Init
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+ Par 2: struct DenyList ( Zu initialisierender struct DenyList)
+ Info: Diese Funktion initialsiert alle Inahlte des übergebenen Strukts DenyList mit den Standardwerten. Diese
+ Funktion sollte nach jedem malloc-Aufruf einer neuen DenyList ausgeführt werden.
+*/
+
+void DenyList_Init(struct PortNetscanConf * ENV,struct DenyList* V)
+{
+ V->Src = 0;
+ V->Count = 0;
+ V->Reason = 0;
+ V->Next = NULL;
+ V->Prior = NULL;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: DenyList_Flush
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2:
+ Info:
+*/
+void DenyList_Flush(struct PortNetscanConf * ENV,struct DenyList* V)
+{
+ V->Src = 0;
+ V->Count = 0;
+ V->Reason = 0;
+ V->Next = NULL;
+ V->Prior = NULL;
+}
+/*
+######################################################################################################################
+#### Class: PortNetscanTree ##########################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_Init
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Info: Diese Funktion initialsiert alle Inahlte des übergebenen Strukts PortNetscanConf mit den Standardwerten.
+ Dieser Struct ist in sich eine Konfigurationsumegebung, die je nach Parametern von IpTables angelegt
+ wird.
+*/
+void PortNetscan_Init(struct PortNetscanConf * ENV)
+{
+ // Alle Zeigervariablen mit NULL initialisieren
+ ENV->RootEntry = NULL;
+ ENV->FirstEndNode = NULL;
+ ENV->LastEndNode = NULL;
+ ENV->FirstDenyListEntry = NULL;
+ ENV->TreeDepth = DEFAULTTREEDEPTH;
+ ENV->TraceTime = DEFAULTTRACETIME;
+ ENV->CleanInterval = DEFAULTCLEANINTERVAL;
+ ENV->NetscanQuota = DEFAULTNETSCANQUOTA;
+ ENV->PortscanQuota = DEFAULTPORTSCANQUOTA;
+ ENV->CombinedQuota = DEFAULTCOMBINEDQUOTA;
+ ENV->BlockTime = DEFAULTBLOCKTIME;
+ ENV->MaxEndNodeCount = DEFAULTENDNODECOUNT;
+ ENV->MaxDenyListCount = DEFAULTDENYLISTCOUNT;
+ ENV->LastClean = getunixtime();
+ ENV->EndNodeCount = 0;
+ ENV->DenyListCount = 0;
+ ENV->TreeCount = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_Flush
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2:
+ Info:
+*/
+void PortNetscan_Flush(struct PortNetscanConf * ENV)
+{
+ // Alle Zeigervariablen mit NULL initialisieren
+ PortNetscan_CleanupAll(ENV);
+ ENV->RootEntry = NULL;
+ ENV->FirstEndNode = NULL;
+ ENV->LastEndNode = NULL;
+ ENV->FirstDenyListEntry = NULL;
+ ENV->EndNodeCount = 0;
+ ENV->TreeDepth = 0;
+ ENV->TraceTime = 0;
+ ENV->CleanInterval = 0;
+ ENV->LastClean = 0;
+ ENV->MaxDenyListCount = 0;
+ ENV->NetscanQuota = 0;
+ ENV->PortscanQuota = 0;
+ ENV->CombinedQuota = 0;
+ ENV->BlockTime = 0;
+ ENV->DenyListCount = 0;
+ ENV->MaxEndNodeCount = 0;
+ ENV->TreeCount = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_Cleanup
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Info: Diese Funktion prüft, ob überwachte Einträge die Maximale Zeit der Überwachung überschritten haben und löscht
+ diese. Eoine Überschreitung dieser Zeit wird aus (Zeit letzer Zugriff) + TraceTime(Überwachungszeit) hergeleitet.
+*/
+void PortNetscan_Cleanup(struct PortNetscanConf * ENV)
+{
+ // Funktionsvariablen
+ struct TreeEndNode * TENTRY = ENV->FirstEndNode;
+ time_t NOW = getunixtime();
+ struct DenyList * DENTRY = ENV->FirstDenyListEntry;
+
+
+ // Überwachungsbaum/-einträge Aufräumen
+ if ( TENTRY != NULL )
+ while ( TENTRY != NULL )
+ {
+ struct TreeEndNode * NEXT = TENTRY->Next;
+ if ( (TENTRY->LastTime + ENV->TraceTime) < NOW)
+ {
+ PortNetscan_DelTreeUnuses(ENV,TENTRY->Parent);
+ PortNetscan_DelTreeEndNode(ENV,TENTRY);
+ }
+ TENTRY=NEXT;
+ }
+
+ // Ablehnungsliste Aufräumen
+ if ( DENTRY != NULL )
+ {
+ while ( DENTRY != NULL )
+ {
+ // Cleaning old Entries
+ if ( (DENTRY->StartDenyTime + ENV->BlockTime) < NOW )
+ {
+ struct DenyList * DNEXT = DENTRY;
+ DENTRY = DENTRY->Next;
+ PortNetscan_DelDenyListEntry(ENV,DNEXT);
+ DNEXT = NULL;
+ continue;
+ }
+ DENTRY = DENTRY->Next;
+ }
+ }
+
+
+ NOW = 0;
+ TENTRY = NULL;
+ DENTRY = NULL;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_Check
+ Conv: PortNetscan
+ Typ: function
+ return: 0 (Ok) / > 0 Quelladdresse ist in DenyList oder wurde in DenyList verschoben
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Quelladresse
+ Par 3: Zieladresse
+ Par 4: Zielport
+ Par 5: Nur Denyliste überprüfen
+ Info: Dies ist die erste Funktion, die aufgerufen werden sollte, wenn ein Packet geprüft werden
+ soll. Hier wird erst aufgeräumt und dann PortNetscan_Add aufgerufen, wenn OnlyCheckDeny = 0 ist.
+*/
+int PortNetscan_Check(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT, unsigned short OnlyCheckDeny)
+{
+ // Funktionsvariablen
+ int RC = 0;
+
+ if ( PortNetscan_CheckDenyList(ENV,SRC) )
+ {
+ RC = 4;
+ }
+ else
+ if ( OnlyCheckDeny == 0 )
+ {
+ time_t NOW = getunixtime();
+ if ( (ENV->LastClean + ENV->CleanInterval) < NOW )
+ {
+ PortNetscan_Cleanup(ENV);
+ ENV->LastClean = NOW;
+ }
+
+ PortNetscan_Add(ENV,SRC,DST,DPT);
+ }
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetTreeDepth
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: unsigned short - Baumtiefe für Suchbaum
+ Info: Diese Funktion setzt die Baumtiefe einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetTreeDepth(struct PortNetscanConf * ENV,unsigned short DEPTH)
+{
+ // Baumtiefe setzen.100000
+ // Nach ausgiebiegen Tests hat sich die Baumtiefe von 4
+ // als die schnellste Baumtiefe herausgestellt
+ int RC = 1;
+
+ if ( ENV->RootEntry != NULL )
+ {
+ // In diesem Fall ist der Baum schon vorhanden - Änderung nicht mehr möglich!!!
+ _printf("SetTreeDepth: Tree allready initialize!!");
+ RC = 0;
+ }
+ else
+ {
+ switch ( DEPTH )
+ {
+ case 1: { ENV->TreeDepth=1; break; }
+ case 2: { ENV->TreeDepth=2; break; }
+ case 4: { ENV->TreeDepth=4; break; }
+ case 8: { ENV->TreeDepth=8; break; }
+ case 16: { ENV->TreeDepth=16; break; }
+ case 32: { ENV->TreeDepth=32; break; }
+ default:
+ {
+ ENV->TreeDepth=DEFAULTTREEDEPTH;
+ RC=0;
+ _printf("SetTreeDepth: Only 1, 2, 4, 8, 16 or 32 values are possible!");
+ break;
+ }
+ }
+ }
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_GetIpV4Parts
+ Conv: PortNetscan
+ Typ: function
+ return: 1 (true) / 0 (false)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2:
+ Info:
+*/
+int PortNetscan_GetIpV4Parts(struct PortNetscanConf * ENV,const u_int32_t IPV4ADDR, u_int32_t * IPPARTS)
+{
+ int RC = 1;
+ unsigned short PARTSIZE = 32 / ENV->TreeDepth;
+ u_int32_t TEMP = IPV4ADDR;
+ int I = 0;
+
+ for ( I=0; I < ENV->TreeDepth; I++)
+ IPPARTS[I] = (((u_int32_t)powpos((unsigned short)2,(unsigned short)PARTSIZE))-1) & (TEMP >> (ENV->TreeDepth-I-1)*PARTSIZE);
+ return RC;
+}
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_CleanupAll
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Info: Vollständiges Aufräumen (Löschen) Aller Einträge in der Überwachungsliste und der Sperrliste
+*/
+void PortNetscan_CleanupAll(struct PortNetscanConf * ENV)
+{
+ // Funktionsvariablen
+ struct TreeEndNode * WORKENTRY = ENV->FirstEndNode;
+ struct DenyList * DENYENTRY = ENV->FirstDenyListEntry;
+
+ if ( WORKENTRY != NULL )
+ while ( WORKENTRY != NULL )
+ {
+ struct TreeEndNode * NEXT = WORKENTRY->Next;
+ PortNetscan_DelTreeUnuses(ENV,WORKENTRY->Parent);
+ PortNetscan_DelTreeEndNode(ENV,WORKENTRY);
+ WORKENTRY=NEXT;
+ NEXT = NULL;
+ }
+
+
+
+ WORKENTRY = NULL;
+
+ if ( DENYENTRY != NULL )
+ {
+ while ( DENYENTRY != NULL )
+ {
+ struct DenyList * NEXT = DENYENTRY->Next;
+ PortNetscan_DelDenyListEntry(ENV,DENYENTRY);
+ DENYENTRY=NEXT;
+ NEXT=NULL;
+ }
+ }
+
+ DENYENTRY = NULL;
+
+
+ if ( ENV->RootEntry != NULL )
+ {
+ _printf("CleanupAll: Fehler: RootEntry ist ungleich NULL!!\n");
+ }
+
+ if ( ENV->FirstEndNode != NULL )
+ {
+ _printf("CleanupAll: Fehler: FirstEndNode ist ungleich NULL!!\n");
+ }
+
+ if ( ENV->LastEndNode != NULL )
+ {
+ _printf("CleanupAll: Fehler: LastEndNode ist ungleich NULL!!\n");
+ }
+
+ if ( ENV->FirstDenyListEntry != NULL )
+ {
+ _printf("CleanupAll: Fehler: FirstDenyList ist ungleich NULL!!\n");
+ }
+
+
+ ENV->RootEntry = NULL;
+ ENV->FirstEndNode = NULL;
+ ENV->LastEndNode = NULL;
+ ENV->FirstDenyListEntry = NULL;
+
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetTraceTime
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Überwachungszeit in Sekunden
+ Info: Diese Funktion setzt die Überwachungszeit eines Hosteintrags in TreeEndNode einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetTraceTime(struct PortNetscanConf * ENV,const unsigned int TRACETIME)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = MAXTRACETIME;
+ if ( TRACETIME <= MAX )
+ ENV->TraceTime = TRACETIME;
+ else
+ {
+ _printf("SetTraceTime: Gesetzte Zeit überschreitet Maximum-Definition, Standardwert wird verwendet!");
+ ENV->TraceTime = DEFAULTTRACETIME;
+ RC = 0;
+ } // Ende if ( TRACETIME < MAX )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetCleanInterval
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Aufräuminterval in Sekunden
+ Info: Diese Funktion setzt den Aufräuminterval einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetCleanInterval(struct PortNetscanConf * ENV,const unsigned int CLEANINTERVAL)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = MAXTCLEANINTERVAL;
+ if ( CLEANINTERVAL <= MAX )
+ ENV->CleanInterval = CLEANINTERVAL;
+ else
+ {
+ _printf("SetCleanInterval: Gesetzte Zeit überschreitet Maximum-Definition, Standardwert wird verwendet!");
+ ENV->CleanInterval = DEFAULTCLEANINTERVAL;
+ RC = 0;
+ } // Ende if ( TRACETIME < MAX )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetPortscanQuota
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Verhältnis (Port/Dest)
+ Info: Diese Funktion setzt den Verhältniswert, ab dem ein Portscan erkannt wird, einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetPortscanQuota(struct PortNetscanConf * ENV,const unsigned int PORTSCANQUOTA)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = MAXPORTSCANQUOTA;
+ if ( PORTSCANQUOTA <= MAX )
+ ENV->PortscanQuota = PORTSCANQUOTA;
+ else
+ {
+ _printf("SetPortscanQuota: Gesetzter Wert überschreitet Maximum-Definition, Standardwert wird verwendet!");
+ ENV->CleanInterval = DEFAULTPORTSCANQUOTA;
+ RC = 0;
+ } // Ende if ( PORTSCANQUOTA < MAX )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetNetscanQuota
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Verhältnis (Dest/Port)
+ Info: Diese Funktion setzt den Verhältniswert, ab dem ein Netscan erkannt wird, einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetNetscanQuota(struct PortNetscanConf * ENV,const unsigned int NETSCANQUOTA)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = MAXNETSCANQUOTA;
+ if ( NETSCANQUOTA <= MAX )
+ ENV->NetscanQuota = NETSCANQUOTA;
+ else
+ {
+ _printf("SetNetscanQuota: Gesetzter Wert überschreitet Maximum-Definition, Standardwert wird verwendet!");
+ ENV->CleanInterval = DEFAULTNETSCANQUOTA;
+ RC = 0;
+ } // Ende if ( NETSCANQUOTA < MAX )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetBlockTime
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Sperrzeit (für einen Eintrag in der DenyList) in Sekunden
+ Info: Setzt die Sperrzeit (für einen Eintrag in der DenyListe). Hier wird die StartZeit des Eintrags immer als Referenz
+ verwendet. Dies bedeutet, dass die Sperrzeit die Sperrzeit nicht verlängert wird, wenn der Rechner in dieser
+ Sperrzeit zugreift.
+*/
+int PortNetscan_SetBlockTime(struct PortNetscanConf * ENV,const unsigned int BLOCKTIME)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = MAXBLOCKTIME;
+
+ if ( BLOCKTIME <= MAX )
+ ENV->BlockTime = BLOCKTIME;
+ else
+ {
+ _printf("SetBlockTime: Gesetzter Wert überschreitet Maximum-Definition, Standardwert wird verwendet!");
+ ENV->BlockTime = DEFAULTBLOCKTIME;
+ RC = 0;
+ } // Ende if ( BLOCKTIME < MAX )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetMaxDenyListCount
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Anzahl Einträge in DenyList
+ Info: Setzt die maximale Anzahl an Einträgen in der DenyList. Wenn dieser
+ später überschritten wird, wird das erste Element aus der Liste entfernt.
+*/
+int PortNetscan_SetMaxDenyListCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = 0;
+ unsigned int MIN = 0;
+
+ MAX = MAXDENYLISTCOUNT;
+ MIN = MINDENYLISTCOUNT;
+
+ if ( MAXDEFINE <= MAX && MAXDEFINE >= MIN)
+ ENV->MaxDenyListCount = MAXDEFINE;
+ else if ( MAXDEFINE < MAX )
+ {
+ _printf("SetMaxDenyListCount: Gesetzter Wert überschreitet Maximum-Definition, Systemmax wird verwendet!");
+ ENV->MaxDenyListCount = MAX;
+ RC = 0;
+ }
+ else
+ {
+ _printf("SetMaxDenyListCount: Gesetzter Wert unterschreitet Minimum-Definition, Systemmin wird verwendet!");
+ ENV->MaxDenyListCount = MIN;
+ RC = 0;
+ } // Ende if ( MAXDEFINE < MAX && MAXDEFINE > MIN )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetNodeCount
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Anzahl Einträge der Überwachungsliste
+ Info: Setzt die maximale Anzahl an Einträgen in der Überwachungsliste. Wenn dieser
+ später überschritten wird, wird das erste Element aus der Liste entfernt.
+*/
+int PortNetscan_SetNodeCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = 0;
+ unsigned int MIN = 0;
+
+ MAX = MAXENDNODECOUNT;
+ MIN = MINENDNODECOUNT;
+
+ if ( MAXDEFINE <= MAX && MAXDEFINE >= MIN)
+ ENV->MaxEndNodeCount = MAXDEFINE;
+ else if ( MAXDEFINE < MAX )
+ {
+ _printf("SetEndNodeCount: Gesetzter Wert überschreitet Maximum-Definition, Systemmax wird verwendet!");
+ ENV->MaxEndNodeCount = MAX;
+ RC = 0;
+ } else
+ {
+ _printf("SetEndNodeCount: Gesetzter Wert unterschreitet Minimum-Definition, Systemmin wird verwendet!");
+ ENV->MaxEndNodeCount = MIN;
+ RC = 0;
+ } // Ende if ( MAXDEFINE < MAX && MAXDEFINE > MIN )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_SetCombinedQuota
+ Conv: PortNetscan
+ Typ: function
+ return: O (false) für FEHLER / 1 (true) für OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Quota
+ Info: Setzt die CombinedQuota für einen überwachten Host, bevor ein CombinedScan erkannt wird. Dieser
+ wird auf (Anzahl Zielhosts) + (Anzahl Zielports) ermittelt.
+*/
+int PortNetscan_SetCombinedQuota(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE)
+{
+ // Funktionsvariablen
+ int RC = 1;
+ unsigned int MAX = 0;
+
+ MAX = MAXCOMBINEDQUOTA;
+
+ if ( MAXDEFINE <= MAX )
+ ENV->CombinedQuota = MAXDEFINE;
+ else
+ {
+ _printf("PortNetscan_SetCombinedQuota: Gesetzter Wert überschreitet Maximum-Definition, Systemmin wird verwendet!");
+ ENV->CombinedQuota = MAX;
+ RC = 0;
+ } // Ende if ( MAXDEFINE < MAX && MAXDEFINE > MIN )
+
+ MAX = 0;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_AddDenyListEntry
+ Conv: PortNetscan
+ Typ: function
+ return: Erstellter DelyList Eintrag
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2:
+ Info:
+*/
+struct DenyList * PortNetscan_AddDenyListEntry(struct PortNetscanConf * ENV,const IpV4Address SRC)
+{
+ // Funktionsvariablen
+ struct DenyList * RC = NULL;
+
+ if ( ENV->FirstDenyListEntry == NULL )
+ {
+ RC = (struct DenyList *)_malloc(sizeof(struct DenyList), GFP_KERNEL);
+ DenyList_Init(ENV,RC);
+ ENV->FirstDenyListEntry = RC;
+ ENV->DenyListCount = 1;
+ }
+ else
+ {
+ RC = ENV->FirstDenyListEntry;
+ /*
+ Prüfung doppelter Einträge kann gesparrt werden, da im
+ normalen fall imm verher geprüft wird, ob der Wert schon
+ vorhanden ist.
+ */
+ while ( RC->Next != NULL) RC = RC->Next;
+
+ if ( ENV->MaxDenyListCount < ENV->DenyListCount )
+ {
+ /*
+ Liste überschreitet Maximum an Einträgen --> erstes Element
+ wird gelöscht, um Platz zu schaffen
+ */
+ _printf("PortNetscan_AddDenyListEntry:Maximale Anzahl an DenyList Einträgen erreicht, der älteste Entrag wird gelöscht und der neue hinzugefügt!");
+ PortNetscan_DelDenyListEntry(ENV,ENV->FirstDenyListEntry);
+ }
+ RC->Next = (struct DenyList *)_malloc(sizeof(struct DenyList), GFP_KERNEL);
+ DenyList_Init(ENV,RC->Next);
+ RC->Next->Prior = RC;
+ RC = RC->Next;
+ ENV->DenyListCount++;
+ }
+
+ RC->Src=SRC;
+ RC->StartDenyTime = getunixtime();
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_CheckDenyList
+ Conv: PortNetscan
+ Typ: function
+ return: 0 OK / > 0 Rechner ist in Sperrliste oder wurde dort hin verschoeben
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Quelladresse
+ Info: Die Funktion überprüft, ab die angegebene Quelladdresse bereits in der Sperrliste
+ vorhanden ist.
+*/
+int PortNetscan_CheckDenyList(struct PortNetscanConf * ENV,const IpV4Address SRC)
+{
+ // Funktionsvariablen
+ struct DenyList * TEMPENTRY = NULL;
+ int RC = 0;
+
+ if ( ENV->FirstDenyListEntry != NULL )
+ {
+ TEMPENTRY = ENV->FirstDenyListEntry;
+ while ( TEMPENTRY != NULL )
+ {
+ if ( TEMPENTRY->Src == SRC )
+ {
+ RC = 1;
+ TEMPENTRY->Count++;
+ break;
+ }
+ TEMPENTRY = TEMPENTRY->Next;
+ }
+ }
+
+ TEMPENTRY = NULL;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_AddTreeEndNode
+ Conv: PortNetscan
+ Typ: function
+ return: Erstellte TreeEndNode
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Quelladresse
+ Par 3: Zieladresse
+ Par 4: Zielport
+ Info:
+*/
+struct TreeEndNode * PortNetscan_AddTreeEndNode(struct PortNetscanConf * ENV,struct TreeNode * LASTTREENODE,IpV4Address SRC , IpV4Address DST, IpV4Port DPT )
+{
+ // Funktionsvariablen
+ struct TreeEndNode * RC = NULL;
+
+ if ( LASTTREENODE != NULL )
+ {
+ if ( LASTTREENODE->Childs != NULL )
+ {
+ RC = (struct TreeEndNode*)LASTTREENODE->Childs;
+ // Erst mal DST
+ // Wenn Fehler dann hier korrigieren
+ if ( RC->EntriesDst == NULL )
+ {
+ // Eintrag in Entries erstellen
+ RC->EntriesDst = (struct TreeEndNodeEntry *)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+ TreeEndNodeEntry_Init(ENV,RC->EntriesDst);
+ RC->EntriesDst->Value = DST;
+ RC->CountDst = 1;
+ }
+ else
+ if (PortNetscan_AddEndTreeEnty(ENV,RC->EntriesDst,DST)) RC->CountDst++;
+
+
+ // Dann mal DPT
+ // Wenn Fehler dann hier korrigieren
+ if ( RC->EntriesDpt == NULL )
+ {
+ // Eintrag in Entries erstellen
+ RC->EntriesDpt = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+ TreeEndNodeEntry_Init(ENV,RC->EntriesDst);
+ RC->EntriesDpt->Value = DPT;
+ RC->CountDpt = 1;
+ } // Ende if ( RC->EntriesDpt == NULL )
+ else
+ if (PortNetscan_AddEndTreeEnty(ENV,RC->EntriesDpt,DPT)) RC->CountDpt++;
+
+
+ }
+ else
+ { // Noch nicht vorhanden - neuen Eintrag erstellen
+
+
+ ENV->EndNodeCount++;
+
+ if ( ENV->EndNodeCount > ENV->MaxEndNodeCount )
+ {
+ PortNetscan_DelTreeUnuses(ENV,ENV->FirstEndNode->Parent);
+ PortNetscan_DelTreeEndNode(ENV,ENV->FirstEndNode);
+ }
+
+ LASTTREENODE->Childs = (struct TreeEndNode*)_malloc(sizeof(struct TreeEndNode), GFP_KERNEL);
+ TreeEndNode_Init(ENV,LASTTREENODE->Childs);
+ RC = (struct TreeEndNode*)LASTTREENODE->Childs;
+ RC->Count = 0;
+ RC->Src = SRC;
+ RC->Parent = LASTTREENODE;
+ RC->FirstTime = getunixtime();
+ // Eintrag in Entries erstellen
+ RC->EntriesDst = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+ RC->EntriesDpt = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+ TreeEndNodeEntry_Init(ENV,RC->EntriesDst);
+ TreeEndNodeEntry_Init(ENV,RC->EntriesDpt);
+ RC->EntriesDpt->Value = DPT;
+ RC->EntriesDst->Value = DST;
+ RC->CountDpt = 1;
+ RC->CountDst = 1;
+
+ if ( ENV->FirstEndNode == NULL )
+ {
+ ENV->FirstEndNode = RC;
+ ENV->LastEndNode = RC;
+ }
+ else
+ {
+ RC->Prior = ENV->LastEndNode;
+ ENV->LastEndNode->Next = RC;
+ ENV->LastEndNode = RC;
+ }
+
+ } // Ende if ( LastTreeNode->Childs != NULL )
+ // Standardwerte zum guten Schluss
+ RC->LastTime = getunixtime();
+ RC->Count++;
+
+ } // Ende if ( LastTreeNode != NULL )
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_AddTreeEndEntry
+ Conv: PortNetscan
+ Typ: function
+ return: 0, wenn Wert(Par 3) schon in der Liste / 1 wenn der Wert (Par 3) hinzugefügt wurde.
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: TreeEndNodeEntry
+ Par 3: Wert, der Hinzugefügt werden soll
+ Info:
+*/
+int PortNetscan_AddEndTreeEnty(struct PortNetscanConf * ENV,struct TreeEndNodeEntry * ENTRY, const u_int32_t VALUE)
+{
+ int RC = 0;
+ int MAXSEARCHLOOPS = 0;
+ int COUNT = 0;
+ struct TreeEndNodeEntry * TEMPENTRY = ENTRY;
+
+ MAXSEARCHLOOPS = MAXENDNODEENTRY;
+
+ if ( ENTRY != NULL )
+ {
+ int ENTRYUSE = 0;
+ while ( MAXSEARCHLOOPS > COUNT ) // Sicherheit, falls andere Speicher überschrieben
+ {
+ if ( TEMPENTRY->Value == VALUE ) { ENTRYUSE = 1; break; }
+ if ( TEMPENTRY->Next == NULL ) break;
+ TEMPENTRY = TEMPENTRY->Next;
+ COUNT++;
+ } // Ende while (true)
+ if ( ! ENTRYUSE )
+ {
+ RC = 1;
+ TEMPENTRY->Next = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+ TreeEndNodeEntry_Init(ENV,TEMPENTRY->Next);
+ TEMPENTRY->Next->Value = VALUE;
+ } // Ende if ( ! ENTRYUSEDST )
+
+ }
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_Add
+ Conv: PortNetscan
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Quelladresse
+ Par 3: Zieladresse
+ Par 4: Zielport
+ Info: Sollte durch PortNetscan_Check aufgerufen werden, nachdem alle alten Einträge
+ aus den Listen (Sperrliste/Überwachungsliste) entfernt wurden.
+*/
+int PortNetscan_Add(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT)
+{
+ // Funtionsvariablen
+ int RC = 0;
+ struct TreeNode * WORKTREE = NULL;
+ struct TreeEndNode * WORKENTRY = NULL;
+
+
+ u_int32_t * IPPARTS = NULL;
+ IPPARTS = (u_int32_t*)_malloc( sizeof(u_int32_t) * ENV->TreeDepth, GFP_KERNEL);
+
+ PortNetscan_GetIpV4Parts(ENV,SRC,IPPARTS);
+
+ WORKTREE = ENV->RootEntry;
+
+ WORKTREE = PortNetscan_AddTree(ENV,WORKTREE,IPPARTS,0);
+ WORKENTRY = PortNetscan_AddTreeEndNode(ENV,WORKTREE,SRC,DST,DPT);
+
+ if ( (WORKENTRY->CountDpt/WORKENTRY->CountDst) >= ENV->PortscanQuota ||
+ (WORKENTRY->CountDst/WORKENTRY->CountDpt) >= ENV->NetscanQuota ||
+ (WORKENTRY->CountDst+WORKENTRY->CountDpt) >= ENV->CombinedQuota)
+ {
+ struct DenyList * TEMPDENY = PortNetscan_AddDenyListEntry(ENV,WORKENTRY->Src);
+ if ( TEMPDENY != NULL ) // Nur zur Sicherheit
+ {
+ TEMPDENY->Count++;
+ if ( (WORKENTRY->CountDpt/WORKENTRY->CountDst) >= ENV->PortscanQuota ) TEMPDENY->Reason = REASONPORTSCAN;
+ else if ( (WORKENTRY->CountDst/WORKENTRY->CountDpt) >= ENV->NetscanQuota ) TEMPDENY->Reason = REASONNETSCAN;
+ else if ( (WORKENTRY->CountDst+WORKENTRY->CountDpt) >= ENV->CombinedQuota ) TEMPDENY->Reason = REASONCOMPINED;
+ else TEMPDENY->Reason = REASONUNKNOWN;
+ }
+
+ PortNetscan_DelTreeUnuses(ENV,WORKENTRY->Parent);
+ PortNetscan_DelTreeEndNode(ENV,WORKENTRY);
+ TEMPDENY = NULL;
+ RC = 4;
+ }
+
+
+ WORKENTRY = NULL;
+ WORKTREE = NULL;
+
+ _free(IPPARTS);
+ IPPARTS = NULL;
+
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_AddTree
+ Conv: PortNetscan
+ Typ: function
+ return: Erstellter Baumknoten
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Parent
+ Par 3: Vektor Teile Quelladresse
+ Par 4: Aktuell erreichte Tiefe
+ Info: Hinweis: Diese Funktion wird rekusiv aufgerufen!
+*/
+struct TreeNode * PortNetscan_AddTree(struct PortNetscanConf * ENV,struct TreeNode * TREENODE,const u_int32_t * IPPARTS,const unsigned short DEPTH)
+{
+ struct TreeNode * RC = TREENODE;
+ int USED = 0;
+ // Prüfen, ob eine Struktur schon initialisiert
+ if ( ENV->RootEntry == NULL )
+ {
+ RC = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+ ENV->TreeCount++;
+ TreeNode_Init(ENV,RC);
+ ENV->RootEntry = RC;
+ RC->TreeValue = IPPARTS[DEPTH];
+ if ( DEPTH < (ENV->TreeDepth-1) )
+ {
+ RC->Childs = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+ ENV->TreeCount++;
+ TreeNode_Init(ENV,(struct TreeNode*)RC->Childs);
+ ((struct TreeNode*)RC->Childs)->Parent = RC;
+ ((struct TreeNode*)RC->Childs)->TreeValue = IPPARTS[DEPTH+1];
+ RC=PortNetscan_AddTree(ENV,(struct TreeNode*)RC->Childs,IPPARTS,DEPTH+1);
+ }
+ } // Ende if ( FirstEntry == NULL )
+ else
+ {
+ while (1)
+ {
+ if ( RC->TreeValue == IPPARTS[DEPTH] ) { USED = 1; break; }
+ if ( RC->Next == NULL ) break;
+ else RC=RC->Next;
+ } // Ende while (true)
+
+ if ( USED == 0 )
+ {
+ RC->Next = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+ ENV->TreeCount++;
+ TreeNode_Init(ENV,RC->Next);
+ RC->Next->Prior = RC;
+ RC = RC->Next;
+ RC->TreeValue = IPPARTS[DEPTH];
+
+ if ( DEPTH < (ENV->TreeDepth-1) )
+ {
+ RC->Childs = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+ ENV->TreeCount++;
+ TreeNode_Init(ENV,(struct TreeNode*)RC->Childs);
+ ((struct TreeNode*)RC->Childs)->Parent = RC;
+ ((struct TreeNode*)RC->Childs)->TreeValue = IPPARTS[DEPTH+1];
+ RC = PortNetscan_AddTree(ENV,(struct TreeNode*)RC->Childs,IPPARTS,DEPTH+1);
+ } // Ende if ( DEPTH < TreeDepth-1)
+ }
+ else
+ {
+ if ( DEPTH < (ENV->TreeDepth-1) )
+ {
+ if ( RC->Childs == NULL )
+ {
+ RC->Childs = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+ ENV->TreeCount++;
+ TreeNode_Init(ENV,(struct TreeNode*)RC->Childs);
+ ((struct TreeNode*)RC->Childs)->Parent = RC;
+ ((struct TreeNode*)RC->Childs)->TreeValue = IPPARTS[DEPTH+1];
+ }
+ RC = PortNetscan_AddTree(ENV,(struct TreeNode*)RC->Childs,IPPARTS,DEPTH+1);
+ } // Ende if ( DEPTH < TreeDepth-1)
+
+
+ } // Ende if ( USED )
+
+ } // Ende if ( RC == NULL )
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_DelDenyListEntry
+ Conv: PortNetscan
+ Typ: function
+ return: 0 (False) im Fehlerfall/ 1 (True) OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Zeiger auf zu löschenden Sperreintrags
+ Info: Löscht einen Eintrag aus der Sperrliste
+*/
+int PortNetscan_DelDenyListEntry(struct PortNetscanConf * ENV,struct DenyList * ENTRY)
+{
+ // Funktionsvariablen
+ int RC = 1;
+
+ if ( (ENTRY != NULL) && (ENV->FirstDenyListEntry != NULL) )
+ {
+ if ( (ENTRY->Next != NULL) && (ENTRY->Prior != NULL) )
+ {
+ ENTRY->Next->Prior = ENTRY->Prior;
+ ENTRY->Prior->Next = ENTRY->Next;
+
+ }
+ else if ( (ENTRY->Next != NULL) && (ENTRY->Prior == NULL) )
+ {
+ ENV->FirstDenyListEntry = ENTRY->Next;
+ ENTRY->Next->Prior = NULL;
+ }
+ else if ( (ENTRY->Next == NULL) && (ENTRY->Prior != NULL) )
+ {
+ ENTRY->Prior->Next = NULL;
+ }
+ else
+ ENV->FirstDenyListEntry = NULL;
+
+ DenyList_Flush(ENV,ENTRY);
+ _free(ENTRY);
+
+ ENV->DenyListCount--;
+ ENTRY = NULL;
+ }
+ else
+ RC = 0;
+
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_DelTreeEndNode
+ Conv: PortNetscan
+ Typ: function
+ return: 0 (False) im Fehlerfall / 1 (True) OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Zeiger auf zu löschenden Überwachungeintrag
+ Info:
+*/
+int PortNetscan_DelTreeEndNode ( struct PortNetscanConf * ENV,struct TreeEndNode * ENTRY )
+{
+ /*
+ Funktion: nicht verwendete Element aus EndKnoten Kette entfernen
+ */
+
+ // Funktionsvariablen
+ int RC = 1;
+ struct TreeEndNodeEntry * TEMPENDNODEENTRY = NULL;
+
+ if ( ENTRY != NULL )
+ {
+ struct TreeNode * TREENODE = ENTRY->Parent;
+ //struct TreeEndNodeEntry * TREENODEENTRY = NULL;
+
+
+ // Prüfen auf lineare Kette EndNodes
+ if ( (ENTRY->Next == NULL) && (ENTRY->Prior == NULL) )
+ {
+ ENV->LastEndNode = NULL;
+ ENV->FirstEndNode = NULL;
+ }
+ else if ( ENTRY->Next == NULL )
+ {
+ ENV->LastEndNode = ENTRY->Prior;
+ ENTRY->Prior->Next = NULL;
+ }
+ else if ( ENTRY->Prior == NULL )
+ {
+ ENV->FirstEndNode = ENTRY->Next;
+ ENTRY->Next->Prior = NULL;
+ }
+ else
+ {
+ ENTRY->Next->Prior = ENTRY->Prior;
+ ENTRY->Prior->Next = ENTRY->Next;
+ }
+
+ TEMPENDNODEENTRY = ENTRY->EntriesDpt;
+ while ( TEMPENDNODEENTRY != NULL )
+ {
+ struct TreeEndNodeEntry * NEXT = TEMPENDNODEENTRY->Next;
+ TreeEndNodeEntry_Flush(ENV,TEMPENDNODEENTRY);
+ _free(TEMPENDNODEENTRY);
+ TEMPENDNODEENTRY=NULL;
+ TEMPENDNODEENTRY = NEXT;
+ }
+ ENTRY->EntriesDpt = NULL;
+
+ TEMPENDNODEENTRY = ENTRY->EntriesDst;
+ while ( TEMPENDNODEENTRY != NULL )
+ {
+ struct TreeEndNodeEntry * NEXT = TEMPENDNODEENTRY->Next;
+ TreeEndNodeEntry_Flush(ENV,TEMPENDNODEENTRY);
+ _free(TEMPENDNODEENTRY);
+ TEMPENDNODEENTRY=NULL;
+ TEMPENDNODEENTRY = NEXT;
+ }
+ ENTRY->EntriesDst = NULL;
+
+ TreeEndNode_Flush(ENV,ENTRY);
+ _free(ENTRY);
+ ENTRY = NULL;
+
+ ENV->EndNodeCount--;
+ TREENODE = NULL;
+ }
+
+ TEMPENDNODEENTRY = NULL;
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: PortNetscan_DelTreeUnuses
+ Conv: PortNetscan
+ Typ: function
+ return: 0 (False) im Fehlerfall / 1 (True) OK
+ Par 1: PortNetscanConf (Konfigurationsumgebung)
+ Par 2: Aktuell betreffender Baumknoten
+ Info: Hinweis: Funktion wird rekusiv aufgerufen!
+ Diese Funktion löscht nach einem Löschen eines Überwachungseintrag die
+ die nicht mehr benötigten Einträge aus dem Suchbaum.
+*/
+int PortNetscan_DelTreeUnuses(struct PortNetscanConf * ENV,struct TreeNode *TREENODE)
+{
+ /*
+ Funktion: Nicht verwendete Elemente im Baum löschen.
+ Hinweis: rekusiver Aufruf zum Löschen der Elemente im Baum. Hierbei wird die
+ Tiefste (die bedeutet Ende, nicht das ROOT-Element) beim jeweiligen Aufruf verwendet.
+ */
+ // Funktionsvariablen
+ int RC = 1;
+ if ( (TREENODE == NULL) || (ENV->RootEntry == NULL) )
+ {
+ RC = 0;
+ /*
+ static struct In diesem Fall wurde der Baum nicht sauber gelöscht - irgendeine Zeiger
+ auf ein abhängiges Element wurde versehendlich gelöscht oder
+ auf NULL gesetzt
+ */
+ _printf("PortNetscan_DelTreeUnuses:Fehler beim Aufräumen des Baumes");
+ }
+ else
+ {
+ if ( (TREENODE->Next == NULL) && (TREENODE->Prior == NULL) )
+ {
+ /*
+ Dies ist der einzige Eintrag in dieser Baumebene. Dies bedeutet, dass
+ auch das Elternelement gelöscht werden kann - dieses muss aber ebenfalls ge
+ */
+ if (TREENODE->Parent != NULL )
+ { // Noch nicht die oberste Baumebene erreicht
+ PortNetscan_DelTreeUnuses(ENV,TREENODE->Parent);
+ }
+ else
+ {
+ ENV->RootEntry = NULL;
+ } // Ende if (TREENODE->Parent != NULL )
+
+ TreeNode_Flush(ENV,TREENODE);
+ _free(TREENODE);
+ ENV->TreeCount--;
+ }
+ else
+ { /*
+ In diesem Fall sind noch andere Elemente auf dieser Ebene vorhanden. Dies
+ bedeutet, dass das Löschen vom Parent-Element nicht versucht wird. Das Element selbst
+ wird aber gelöscht.
+
+ Zur Fehlerdiagnose wurden die Schritte sehr ausführlich ausprogrammiert. Nach Tests an
+ der Fachhochschule ist der Geschwindigkeitsverlust aber nicht messbar!
+ */
+ if ( TREENODE->Next != NULL && TREENODE->Prior != NULL )
+ {
+ /*
+ Vorgänger- mit Nachfolgerelement sind vorhanden und
+ werden miteinander verknüpft
+ */
+ TREENODE->Next->Prior = TREENODE->Prior;
+ TREENODE->Prior->Next = TREENODE->Next;
+ }
+ else if ( TREENODE->Prior != NULL && TREENODE->Next == NULL )
+ {
+ /*
+ Ein Vorgängerelement, aber kein Nachfolgerelement vorhanden. Das
+ Nachfolgerelement des Vorgängerelements wird auf NULL gesetzt.
+ */
+ TREENODE->Prior->Next = NULL;
+ }
+ else if ( TREENODE->Prior == NULL && TREENODE->Next != NULL )
+ {
+ /*
+ Kein Vorgängerelement, aber ein Nachfolgerelement vorhanden. Das
+ Vorgängerelement des Nachfolgerelements wird auf NULL gesetzt.
+ */
+ TREENODE->Next->Prior = NULL;
+ if ( TREENODE->Parent == NULL )
+ {
+ /*
+ Wenn in der obersten Baumebene (RootEbene) muss der
+ Zeiger für das Erste Element auf das Nachfolgerelement gesetzt werden.
+ */
+ ENV->RootEntry = TREENODE->Next;
+ TREENODE->Next->Parent = NULL;
+ }
+ else
+ {
+ TREENODE->Next->Parent = TREENODE->Parent;
+ TREENODE->Parent->Childs = TREENODE->Next;
+ }
+
+ }
+ TreeNode_Flush(ENV,TREENODE);
+ _free(TREENODE);
+ ENV->TreeCount--;
+ } // Ende if ( TREENODE->Next == NULL && TREENODE->Prior == NULL )
+ }
+
+ // Zurücksetzen verwendeter Funktionsvariablen
+ TREENODE = NULL;
+
+ return RC;
+}
+
+/*
+#######################################################################################################################
+Globaler Bereich - Funktionen außerhalb der virt. Namensräume
+#######################################################################################################################
+*/
+
+static struct IptGlobalConfStruct IptGlobalConf;
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: IptGetPortNetscanEnv
+ Conv: Global
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: Übergebener INFO-Strukt von IpTables
+ Info:
+*/
+
+static struct PortNetscanEnv * IptGetPortNetscanEnv (struct ipt_PORTNETSCAN_info INFO)
+{
+ // Funktionsvariablen
+ struct PortNetscanEnv * RC = NULL;
+ int USE = 0;
+
+ if ( IptGlobalConf.FirstPortNetscan == NULL )
+ {
+ RC = (struct PortNetscanEnv*)_malloc(sizeof(struct PortNetscanEnv),GFP_KERNEL);
+ IptGlobalConf.FirstPortNetscan = RC;
+ RC->Next = NULL;
+ RC->Prior = NULL;
+
+ PortNetscan_Init(&RC->ConfEntries);
+ RC->tree_depth = INFO.tree_depth;
+ RC->trace_time = INFO.trace_time;
+ RC->clean_interval = INFO.clean_interval;
+ RC->port_scan_quota = INFO.port_scan_quota;
+ RC->net_scan_quota = INFO.net_scan_quota;
+ RC->max_deny_entries = INFO.max_deny_entries;
+ RC->max_trace_entries = INFO.max_trace_entries;
+ RC->block_time = INFO.block_time;
+ RC->combined_quota = INFO.combined_quota;
+ PortNetscan_SetTreeDepth (&RC->ConfEntries,INFO.tree_depth);
+ PortNetscan_SetTraceTime (&RC->ConfEntries,INFO.trace_time);
+ PortNetscan_SetCleanInterval (&RC->ConfEntries,INFO.clean_interval);
+ PortNetscan_SetPortscanQuota (&RC->ConfEntries,INFO.port_scan_quota);
+ PortNetscan_SetNetscanQuota (&RC->ConfEntries,INFO.net_scan_quota);
+ PortNetscan_SetMaxDenyListCount (&RC->ConfEntries,INFO.max_deny_entries);
+ PortNetscan_SetNodeCount (&RC->ConfEntries,INFO.max_trace_entries);
+ PortNetscan_SetBlockTime (&RC->ConfEntries,INFO.block_time);
+ PortNetscan_SetCombinedQuota (&RC->ConfEntries,INFO.combined_quota);
+ IptGlobalConf.Conf_Count++;
+ }
+ else
+ {
+ RC = IptGlobalConf.FirstPortNetscan;
+ while (1)
+ {
+ if ( RC->tree_depth == INFO.tree_depth &&
+ RC->trace_time == INFO.trace_time &&
+ RC->clean_interval == INFO.clean_interval &&
+ RC->port_scan_quota == INFO.port_scan_quota &&
+ RC->net_scan_quota == INFO.net_scan_quota &&
+ RC->max_deny_entries == INFO.max_deny_entries &&
+ RC->max_trace_entries == INFO.max_trace_entries &&
+ RC->block_time == INFO.block_time &&
+ RC->combined_quota == INFO.combined_quota)
+ {
+ USE = 1;
+ break;
+ }
+ if ( RC->Next == NULL ) break;
+ RC = RC->Next;
+ }
+ if ( USE != 1 )
+ {
+ RC->Next = (struct PortNetscanEnv*)_malloc(sizeof(struct PortNetscanEnv),GFP_KERNEL);
+ RC->Next->Prior = RC;
+ RC = RC->Next;
+ RC->Next = NULL;
+
+ PortNetscan_Init(&RC->ConfEntries);
+ RC->tree_depth = INFO.tree_depth;
+ RC->trace_time = INFO.trace_time;
+ RC->clean_interval = INFO.clean_interval;
+ RC->port_scan_quota = INFO.port_scan_quota;
+ RC->net_scan_quota = INFO.net_scan_quota;
+ RC->max_deny_entries = INFO.max_deny_entries;
+ RC->max_trace_entries = INFO.max_trace_entries;
+ RC->block_time = INFO.block_time;
+ RC->combined_quota = INFO.combined_quota;
+ PortNetscan_SetTreeDepth (&RC->ConfEntries,INFO.tree_depth);
+ PortNetscan_SetTraceTime (&RC->ConfEntries,INFO.trace_time);
+ PortNetscan_SetCleanInterval (&RC->ConfEntries,INFO.clean_interval);
+ PortNetscan_SetPortscanQuota (&RC->ConfEntries,INFO.port_scan_quota);
+ PortNetscan_SetNetscanQuota (&RC->ConfEntries,INFO.net_scan_quota);
+ PortNetscan_SetMaxDenyListCount (&RC->ConfEntries,INFO.max_deny_entries);
+ PortNetscan_SetNodeCount (&RC->ConfEntries,INFO.max_trace_entries);
+ PortNetscan_SetBlockTime (&RC->ConfEntries,INFO.block_time);
+ PortNetscan_SetCombinedQuota (&RC->ConfEntries,INFO.combined_quota);
+ IptGlobalConf.Conf_Count++;
+ }
+ }
+
+
+ USE = 0;
+ RC->LastUse = getunixtime();
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: IptCleanupAll
+ Conv: Global
+ Typ: function
+ return: void (keine Rückgabewerte)
+ Par 1: Alle Löschen
+ Info: Globale Aufräumfunktion, bei über Par 1 = 1 werden alle Konfiguration mit allen angehängten Listen
+ gelöscht. Wenn übergebener Par 1 = 0 ist, werden nur die Normalen Aufräumaktionen in den Einzelnen
+ Konfigurationsumgebungen gelöscht.
+*/
+static void IptCleanupAll(int FORCE)
+{
+ // Funktionsvariablen
+ struct PortNetscanEnv * TEMP = IptGlobalConf.FirstPortNetscan;
+ struct PortNetscanEnv * NEXT = NULL;
+
+ if ( IptGlobalConf.FirstPortNetscan != NULL )
+ {
+ while ( TEMP != NULL )
+ {
+ NEXT = TEMP->Next;
+ if ( FORCE == 1 )
+ PortNetscan_Flush(&TEMP->ConfEntries);
+ else
+ PortNetscan_Cleanup(&TEMP->ConfEntries);
+
+ if ( (TEMP->LastUse + GLOBALCLEANUP) > getunixtime() && TEMP->ConfEntries.RootEntry == NULL && TEMP->ConfEntries.FirstEndNode == NULL && TEMP->ConfEntries.FirstDenyListEntry == NULL )
+ {
+ if ( TEMP->Prior == NULL && TEMP->Next == NULL )
+ {
+ IptGlobalConf.FirstPortNetscan = NULL;
+ }
+ else if ( TEMP->Prior == NULL && TEMP->Next != NULL )
+ {
+ TEMP->Next->Prior = NULL;
+ IptGlobalConf.FirstPortNetscan = TEMP->Next;
+ }
+ else if ( TEMP->Prior != NULL && TEMP->Next == NULL )
+ {
+ TEMP->Prior->Next = NULL;
+ }
+ else
+ {
+ TEMP->Next->Prior = TEMP->Prior;
+ TEMP->Prior->Next = TEMP->Next;
+ } // Ende if ( TEMP->Prior == NULL && TEMP->Next == NULL )
+
+ _free(TEMP);
+ IptGlobalConf.Conf_Count--;
+ } // Ende if if ( TEMP->ConfEntries.RootEntry == NULL && TEMP->ConfEntries.FirstEndNode == NULL && TEMP->ConfEntries.FirstDenyListEntry == NULL )
+ TEMP = NEXT;
+
+ } // Ende while ( TEMP != NULL )
+
+ } // Ende if ( TEMP != NULL )
+
+ IptGlobalConf.LastCleanup = getunixtime();
+
+ TEMP = NULL;
+ NEXT = NULL;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: IptCheckPacket
+ Conv: Global
+ Typ: function
+ return: int (> 0 weißt IpTables an, das Packet hat die Regel erfüllt)
+ Par 1: Übergebener INFO-Strukt von IpTables
+ Par 2: Quelladresse
+ Par 3: Zieladresse
+ Par 4: Zielport
+ Info: Globale Aufräumfunktion, bei über Par 1 = 1 werden alle Konfiguration mit allen angehängten Listen
+ gelöscht. Wenn übergebener Par 1 = 0 ist, werden nur die Normalen Aufräumaktionen in den Einzelnen
+ Konfigurationsumgebungen gelöscht.
+*/
+static int IptCheckPacket(struct ipt_PORTNETSCAN_info INFO,IpV4Address SRC, IpV4Address DST, IpV4Port DPT)
+{
+ // Funktionsvariablen
+ int RC = 0;
+ struct PortNetscanEnv * ENV = NULL;
+
+ ENV = IptGetPortNetscanEnv(INFO);
+
+ RC = PortNetscan_Check(&ENV->ConfEntries,SRC,DST,DPT,INFO.check_deny_entries);
+
+ return RC;
+}
+
+// Ab hier Kernel
+
+//-------------------------------------------------------------------------------------------------------------------
+
+#ifdef __KERNEL__
+/*
+######################################################################################################################
+#### KernelFunktionen ################################################################################################
+######################################################################################################################
+*/
+
+// Standard Funktionen für IpTables
+
+static spinlock_t PORTNETSCAN_SPINLOCK = SPIN_LOCK_UNLOCKED;
+
+// IpTables: Registrierte Match-Funktion
+static int IptMatchEntry (
+ const struct sk_buff * SBK,
+ const struct net_device * INDEV,
+ const struct net_device * OUTDEV,
+ const struct xt_match *MATCH,
+ const void * MATCHINFO,
+ int OFFSET,
+ unsigned int PROTOOF,
+ int * HOTDROP)
+{
+ // Funktionsvariablen
+ int RC = 0;
+ struct iphdr * IP_HEADER = NULL;
+ struct tcphdr * TCP_UDP_HEADER = NULL;
+ const struct ipt_PORTNETSCAN_info * INFO;
+ u_int16_t DPT = 0;
+
+ INFO = MATCHINFO;
+
+ IP_HEADER = SBK->nh.iph;
+ /* Sanity check */
+ //if (ntohs(IP_HEADER->frag_off) & IP_OFFSET)
+ //{
+ // DEBUGP("PSD: sanity check failed\n");
+ // return 0;
+ //}
+
+ if ( IP_HEADER->protocol == IPPROTO_TCP || IP_HEADER->protocol == IPPROTO_UDP )
+ {
+ TCP_UDP_HEADER = (struct tcphdr*)((u_int32_t *)IP_HEADER + IP_HEADER->ihl);
+ // its dirty
+ DPT = TCP_UDP_HEADER->dest;
+ // Object Sperren
+ spin_lock(&PORTNETSCAN_SPINLOCK);
+ if ( IptCheckPacket(*INFO,IP_HEADER->saddr,IP_HEADER->daddr,DPT) != 0 ) RC =1;
+
+ // Object entsperren
+ spin_unlock(&PORTNETSCAN_SPINLOCK);
+ }
+ return RC;
+}
+/*
+######################################################################################################################
+#### IpTablesInitStruct ##############################################################################################
+######################################################################################################################
+*/
+static int IptCheckEntry (
+ const char * TABLENAME,
+ const void * INF,
+ const struct xt_match *MATCH,
+ void * MATCHINFO,
+ unsigned int MATCHSIZE,
+ unsigned int HOOKMASK )
+{
+ // Funktionsvariablen
+ int RC = 1; // 1 = OK!!!
+
+
+
+ return RC;
+}
+
+
+// IpTables Init Struct
+static struct ipt_match ipt_portnetscan =
+{
+ .name = "PORTNETSCAN",
+ .match = IptMatchEntry,
+ .matchsize = sizeof(struct ipt_PORTNETSCAN_info),
+ .proto = IPPROTO_IP,
+ .checkentry = IptCheckEntry,
+ .destroy = NULL,
+ .me = THIS_MODULE
+};
+/*
+######################################################################################################################
+#### End: IpTablesInitStruct #########################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: Kernel_CreateProcmemPufferAddEntry
+ Conv: Global/Kernel
+ Typ: function
+ return: Anzahl der gespeicherten Text-Zeichen in der verketteten Liste
+ Par 1: String, der in der Kette engehängt werden soll
+ Info: Hinzufügen eines Elements zur Kernelausgabeliste, wenn eine "read_proc" Funktion
+ Aufgerufen wurd
+*/
+int Kernel_CreateProcmemPufferAddEntry(char * LINE)
+{
+ int RC = 0;
+
+ if (IptGlobalConf.FirstOutLine == NULL )
+ {
+ /*
+ Verkettete Liste zur Kernelausgabe ist noch nicht vorhanden. Ersten Element wird
+ im Speicher allokiert und die beiden LeseElemente werden auf den Sselben Speicherplatz verwiesen.
+ */
+ IptGlobalConf.FirstOutLine = (struct KernelOutLinePuffer*)_malloc(sizeof(struct KernelOutLinePuffer), GFP_KERNEL);
+ IptGlobalConf.LastAddOutLine = IptGlobalConf.FirstOutLine;
+ IptGlobalConf.LastPrintOutLine = IptGlobalConf.FirstOutLine;
+ IptGlobalConf.FailBuffer = 0;
+ }
+ else
+ {
+ /*
+ Es sind schon Elemente in der Kernelausgabe vorhanden. In diesem Fall muss ein Element
+ angehängt werden...
+ */
+ IptGlobalConf.LastAddOutLine->Next = (struct KernelOutLinePuffer*)_malloc(sizeof(struct KernelOutLinePuffer), GFP_KERNEL);
+ IptGlobalConf.LastAddOutLine = IptGlobalConf.LastAddOutLine->Next;
+ }
+
+ if ( IptGlobalConf.LastAddOutLine != NULL )
+ {
+ /*
+ Wenn alles glatt gegangen ist, sollte dieses Element nicht NULL sein. Die Daten (Strings) können also in die
+ Struct - Variable Line geschrieben werden.
+ */
+ RC = snprintf(IptGlobalConf.LastAddOutLine->Line,KERNELLINEMAX,"%s",LINE);
+ IptGlobalConf.LastAddOutLine->Next = NULL;
+ }
+
+ return RC;
+
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: Kernel_CreateProcmemPuffer
+ Conv: Global/Kernel
+ Typ: function
+ return: Anzahl der Auszugebenen Zeichen
+ Par X: void (keine)
+ Info: Daten in eine verkettete Liste (Kernelausgabeliste) kopieren. Für
+ jede Zeite wird die Funktion reateProcmemPufferAddEntry(String) aufgerufen, die
+ wiederum das Element an die Liste hängt.
+*/
+int Kernel_CreateProcmemPuffer(void)
+{
+ // Functionsvariablen
+ struct PortNetscanEnv * TEMP = IptGlobalConf.FirstPortNetscan;
+ unsigned int COUNTER = 0;
+ u_int32_t * IPPARTS = (u_int32_t*)_malloc( sizeof(u_int32_t) * 4, GFP_KERNEL);
+ unsigned short PARTSIZE = 8; /* 32/4* */
+ unsigned int TEXTLEN = 0;
+ char STRINGBUFFER[KERNELLINEMAX];
+
+
+ if (IptGlobalConf.FirstOutLine == NULL )
+ {
+
+ spin_lock(&PORTNETSCAN_SPINLOCK);
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"# IpTables PORTNETSCAN MODUL\n# --------------------------\n#\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"G\tCount_Global_Conf: %d\n",IptGlobalConf.Conf_Count);
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"U\tUpdating_Time(Unix): %u\n#\n",(unsigned int)getunixtime());
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"J\tUpdating_Time(jiffies): %u\n",(unsigned int)jiffies);
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"C\tNext_Cleanup_Time(jiffies): %u\n#\n",(unsigned int)Kernel_CleanupTimer.expires);
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"# Conf_Entries\n# ------------\n#\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1 ,"#\tconfn/tree-depth/trace-time/clean-interval/port-scan-quota/net-scan-quota/combined-quota/max-deny-entries/max-trace-entries/block-time/tree-count/endnode-count/denylist-count\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+
+ if ( TEMP != NULL )
+ {
+ COUNTER=0;
+ while ( TEMP != NULL )
+ {
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"L\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
+ COUNTER,TEMP->tree_depth,TEMP->trace_time,TEMP->clean_interval,TEMP->port_scan_quota,
+ TEMP->net_scan_quota,TEMP->combined_quota,TEMP->max_deny_entries,TEMP->max_trace_entries,TEMP->block_time,
+ TEMP->ConfEntries.TreeCount,TEMP->ConfEntries.EndNodeCount,TEMP->ConfEntries.DenyListCount);
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ TEMP = TEMP->Next;
+ COUNTER++;
+ } // Ende while ( TEMP != NULL )
+
+ TEMP = IptGlobalConf.FirstPortNetscan;
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\n# Deny_Entries\n# ------------\n#\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\tconfn/ipaddress/starttime/endtime/count/reason\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ COUNTER=0;
+ while ( TEMP != NULL )
+ {
+ struct DenyList * TEMPDENYENTRY = TEMP->ConfEntries.FirstDenyListEntry;
+ unsigned short I = 0;
+
+ if ( TEMPDENYENTRY != NULL )
+ {
+ while ( TEMPDENYENTRY != NULL )
+ {
+ for ( I=0; I < 4; I++)
+ {
+ IPPARTS[I] = (((unsigned int)powpos((unsigned short)2,(unsigned short)PARTSIZE))-1) & (TEMPDENYENTRY->Src >> (4-I-1)*PARTSIZE);
+ }
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"D\t%d\t%d.%d.%d.%d\t%u\t%u\t%u\t",COUNTER,IPPARTS[3],IPPARTS[2],IPPARTS[1],IPPARTS[0],
+ (unsigned int)TEMPDENYENTRY->StartDenyTime,
+ (unsigned int)TEMPDENYENTRY->StartDenyTime+TEMP->ConfEntries.BlockTime,
+ (unsigned int)TEMPDENYENTRY->Count);
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ if ( TEMPDENYENTRY->Reason == REASONPORTSCAN ) snprintf(STRINGBUFFER,KERNELLINEMAX-1,"portscan_detected\n");
+ else if ( TEMPDENYENTRY->Reason == REASONNETSCAN ) snprintf(STRINGBUFFER,KERNELLINEMAX-1,"netscan_detected\n");
+ else if ( TEMPDENYENTRY->Reason == REASONCOMPINED ) snprintf(STRINGBUFFER,KERNELLINEMAX-1,"netscan_detected\n");
+ else snprintf(STRINGBUFFER,KERNELLINEMAX-1,"unknown\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ TEMPDENYENTRY = TEMPDENYENTRY->Next;
+ }
+ }
+ TEMP = TEMP->Next;
+ TEMPDENYENTRY = NULL;
+ COUNTER++;
+ }
+
+ TEMP = IptGlobalConf.FirstPortNetscan;
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\n# Trace_Entries\n# -------------\n#\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\tconfn/ipaddress/firsttime/lasttime/count/countdst/countdpt\n");
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ COUNTER=0;
+ while ( TEMP != NULL )
+ {
+ struct TreeEndNode * TEMPENDNODEENTRY = TEMP->ConfEntries.FirstEndNode;
+ unsigned short I = 0;
+
+ if ( TEMPENDNODEENTRY != NULL )
+ {
+ while ( TEMPENDNODEENTRY != NULL)
+ {
+ for ( I=0; I < 4; I++)
+ {
+ IPPARTS[I] = (((unsigned int)powpos((unsigned short)2,(unsigned short)PARTSIZE))-1) & (TEMPENDNODEENTRY->Src >> (4-I-1)*PARTSIZE);
+ }
+
+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"T\t%d\t%d.%d.%d.%d\t%u\t%u\t%d\t%d\t%d\n",COUNTER,IPPARTS[3],IPPARTS[2],IPPARTS[1],IPPARTS[0],
+ (unsigned int)TEMPENDNODEENTRY->FirstTime,
+ (unsigned int)TEMPENDNODEENTRY->LastTime,
+ (unsigned int)TEMPENDNODEENTRY->Count,
+ (unsigned int)TEMPENDNODEENTRY->CountDst,
+ (unsigned int)TEMPENDNODEENTRY->CountDpt);
+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+ TEMPENDNODEENTRY = TEMPENDNODEENTRY->Next;
+ }
+ }
+ TEMP = TEMP->Next;
+ TEMPENDNODEENTRY = NULL;
+ COUNTER++;
+ }
+
+ }// Ende if ( TEMP != NULL )
+ spin_unlock(&PORTNETSCAN_SPINLOCK);
+ } // Ende if (IptGlobalConf.FirstOutLine == NULL )
+
+
+ // Freigeben lokaler Funktionsvariablen
+ _free(IPPARTS);
+
+ // Standardwerte für globale und Konfuguraions-Variablen zu setzen
+
+
+ IPPARTS = NULL;
+ return TEXTLEN;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: Kernel_CleanupAll
+ Conv: Global/Kernel
+ Typ: function
+ return: void (keiner)
+ Par 1: void (keine)
+ Info: Nicht mehr verwendet verwendete Teile von Listen (alte IP-Quelladresse und alte DenyListe Einträge)
+ sollten in regelmäßigen Abstängen gelöscht werden. Diese Funktion wird vom Kerneltimer in dem in GLOBALCLEANUP
+ angegebenen Zeitinterval aufgerufen.
+*/
+void Kernel_CleanupAll(unsigned long FORCE)
+{
+ spin_lock(&PORTNETSCAN_SPINLOCK);
+ IptCleanupAll(FORCE);
+ spin_unlock(&PORTNETSCAN_SPINLOCK);
+ /*
+ Zeit neu einplanen
+ * Expires für Task setzen
+ * Task registrieren
+ */
+ Kernel_CleanupTimer.expires = jiffies + (GLOBALCLEANUP*HZ);
+ add_timer(&Kernel_CleanupTimer);
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: Kernel_FlushProcmemPuffer
+ Conv: Global/Kernel
+ Typ: function
+ return: 0 OK / 1 Fehler oder unnötig
+ Par 1: void (keine)
+ Info: Freigeben des reservierten Speichers für die Kernelausgabeliste (verkettete Liste), die
+ durch ein proc_read und dessen Funktionen Erstellt wurde.
+*/
+int Kernel_FlushProcmemPuffer(void)
+{
+ int RC = 0;
+ struct KernelOutLinePuffer * NEXT = NULL;
+
+ if ( IptGlobalConf.FirstOutLine != NULL )
+ {
+ while (IptGlobalConf.FirstOutLine != NULL)
+ {
+ NEXT = IptGlobalConf.FirstOutLine->Next;
+ _free (IptGlobalConf.FirstOutLine);
+ IptGlobalConf.FirstOutLine = NEXT;
+ }
+ }
+ else RC = 1;
+
+ NEXT = NULL;
+ IptGlobalConf.FirstOutLine = NULL;
+ IptGlobalConf.LastPrintOutLine = NULL;
+ IptGlobalConf.LastAddOutLine = NULL;
+ IptGlobalConf.FailBuffer = 0;
+
+ return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Name: Kernel_WriteOutLinePufferToProc
+ Conv: Global/Kernel
+ Typ: function
+ return: Anzahl der Bytes, die in die Variable BUFFER geschrieben wurden
+ Par 1: BUFFER ( zu beschreibender Puffer, der vom Kernel zur Verfügung gestellt wird)
+ Par 2: COUNT ( Anzahl der freien Bytes für Variable BUFFER)
+ Info: Diese Funtion liest Elemente aus der im Modul erstellten Kernelausgabeliste (verkettete Liste)
+ und schreibt diese in der angegeben Pugger (BUFFER) zurück. Hierbei wird darauf geachtet, dass
+ die geschriebenen Bytes den Werte in der Variable COUNT nicht überschreiten.
+*/
+int Kernel_WriteOutLinePufferToProc(char * BUFFER,int COUNT)
+{
+ // Functionsvariablen
+ int RC = 0;
+
+ if ( IptGlobalConf.FirstOutLine != NULL && IptGlobalConf.LastPrintOutLine != NULL )
+ {
+ /*
+ Schritte:
+ 1. Länge der Strings im Element der verketteten Liste Auslesen
+ 2. In BUFFER schreiben
+ a. Wenn genug freier Platz vorhanden ist, werden die Daten in BUFFER zurückgeschrieben
+ b. Wenn nicht genügend Platz vorhanden ist, werden COUNT-1 Bytes geschreiben (-1 für letztes Zeichen,
+ anscheinend braucht der Kernel dies für die interne Verwaltung von Speicherseiten???
+
+
+ Hinweis:
+ Es scheint in einigen Kernelversionen verschiedene Problem mit dem Ende einer Speicherseite zu
+ geben. Aus diesem Grund wird in diesem Modul Ein maximal Zeichen weniger als COUNT ausgegeben. Zudem
+ scheint es gravierende Unterschiede in snprintf zu geben.(Bis glib 2.1 und ab glib 2.1) Deashalb hier
+ eine manuelle Längenprüfung des string und die Rückgabe der Anzahl der geschreibenen Bytes im Fehlerfall
+ "zu wenig Bytes" selbst errechechten und zurückgeben.
+ */
+
+ int L = strlen(IptGlobalConf.LastPrintOutLine->Line+IptGlobalConf.FailBuffer);
+
+ if ( COUNT > KERNELLINEMAX ) COUNT = KERNELLINEMAX;
+
+
+ if ( L <= (COUNT-1) )
+ {
+ RC = snprintf(BUFFER,COUNT,"%s",IptGlobalConf.LastPrintOutLine->Line+IptGlobalConf.FailBuffer);
+ IptGlobalConf.LastPrintOutLine = IptGlobalConf.LastPrintOutLine->Next;
+ IptGlobalConf.FailBuffer = 0;
+ }
+ else
+ {
+ RC = snprintf(BUFFER,COUNT-1,"%s",IptGlobalConf.LastPrintOutLine->Line+IptGlobalConf.FailBuffer);
+ IptGlobalConf.FailBuffer = COUNT -1;
+ RC = COUNT-1;
+ }
+ }
+ return RC;
+}
+
+int Kernel_ReadProcmem(char * BUFFER, char ** START, off_t OFFSET, int COUNT, int *EOF, void * DATA)
+{
+ int LEN=0;
+ /*
+ Falls erster Aufruf, ist OFFSET = 0. In diesem Fall werden
+ die Daten gesammelt und in einer verketteten Liste hinterlegt.
+ */
+ if ( OFFSET == 0 )
+ {
+ /*
+ Um die SpinLock-Zeit im Kernel so kurz wir nötig zu haten, werden die Daten
+ zuerst einmal in der Funktion Kernel_CreateProcmemPuffer() in einer einfachen Verketten Liste
+ gesammelt und dann ausgegeben (Taufe für Kommetare Kernelausgabeliste). Wenn dies fehlschlägt,
+ wird der Speicher eintweder gerade verwendet, oder es wurden nicht alle Zeilen in einem vorherigen Aufruf
+ nicht abgearbeitet. Dies kann zum Beispiel beim Aufruf mit less passieren, da less nur eine bestimmte Anzahl
+ von Zeilen in den eigenen Puffer liest.
+ */
+ if (Kernel_CreateProcmemPuffer() == 0)
+ {
+ *EOF = 1;
+ return sprintf(BUFFER,"... more lines in old buffer ..\n");
+ }
+ }
+
+ /*
+ Daten aus der verketteten Liste (Kernelausgabeliste) lesen und die geschriebenen
+ Bytes in LEN anspeichern.
+ */
+ LEN = Kernel_WriteOutLinePufferToProc(BUFFER,COUNT);
+
+ /*
+ Im Fall, dass von der Funktion Kernel_WriteOutLinePufferToProc 0 zurückgegeben wird, sollte
+ das lesen der verketten Liste (Kernelausgabeliste) beendet sein. Falls der Speicher nicht ausreichen
+ sollte, wird allerdings ebenfalls 0 zurückgegeben, dies ist beabsichtigt, da die Ausgabe dann in jedem
+ Fall abgebrochen werden soll.
+ */
+ if ( LEN == 0 )
+ {
+ // Fehler oder letztes Element
+ *EOF = 1;
+ Kernel_FlushProcmemPuffer();
+ }
+ else
+ {
+ *EOF=1;
+ *START=BUFFER;
+ }
+ return LEN;
+}
+// Kernel Proc Initionlize
+void Kernel_CreateProcEnv(void)
+{
+ create_proc_read_entry("portnetscan",0,proc_net_stat,Kernel_ReadProcmem,NULL);
+}
+
+void Kernel_DeleteProcEnv(void)
+{
+ remove_proc_entry("portnetscan",proc_net_stat);
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+INIT / EXIT
+*/
+static int __init init(void)
+{
+ int RC = 0;
+ printk("RGL PORTNETSCAN INIT\n");
+ printk("PORTNETSCAN Version: 0.1\n");
+ printk("PORTNETSCAN Last Change: 20.06.2006\n");
+
+ memset (&IptGlobalConf,0,sizeof(struct IptGlobalConfStruct));
+ memset (&PORTNETSCAN_SPINLOCK,0,sizeof(spinlock_t));
+
+ /*
+ Initialisieren der Globalen Umgebung
+ */
+ IptGlobalConf.FirstPortNetscan = NULL;
+ IptGlobalConf.FirstOutLine = NULL;
+ IptGlobalConf.LastPrintOutLine = NULL;
+ IptGlobalConf.LastAddOutLine = NULL;
+ IptGlobalConf.Conf_Count = 0;
+ IptGlobalConf.FailBuffer = 0;
+ spin_lock_init(&PORTNETSCAN_SPINLOCK);
+
+ /*
+ Tasks
+ Timer für Aufräum- und Cleanup setzen
+ 1. Initialisieren des Timers
+ 2. Funktion beim Timeraufrufs setzen
+ 3. Übergabeparameter der aufgerufenen Funktion setzen
+ 4. Nächsten Interval-Aufruf setzen
+ 5. Timer im Kernel als Task hinzufügen
+
+ */
+ init_timer(&Kernel_CleanupTimer);
+ Kernel_CleanupTimer.function = Kernel_CleanupAll;
+ Kernel_CleanupTimer.data = 0; // Kein FORCE=1 setzen!!! da sonst alle einträge immer gelöscht werden
+ Kernel_CleanupTimer.expires = jiffies + (GLOBALCLEANUP*HZ);
+ add_timer(&Kernel_CleanupTimer);
+
+
+ RC = ipt_register_match(&ipt_portnetscan);
+
+ /*
+ Initialisieren von Proc-Dateien und Verzeichnissen
+ */
+ Kernel_CreateProcEnv();
+
+
+
+ return RC;
+}
+
+
+static void __exit fini(void)
+{
+ /*
+ Erst Timer-Tasks Löschen
+ */
+
+ del_timer_sync( &Kernel_CleanupTimer );
+
+ printk("RGL PORTNETSCAN FLUSH\n");
+ /*
+ Aufräumen aller Ressourcen
+ 1. Proc-Einträge Löschen
+ 2. Einträge in verketten Listen und Bäumen löschen
+ 3. Unregister des Moduls
+ */
+ Kernel_DeleteProcEnv();
+ spin_lock(&PORTNETSCAN_SPINLOCK);
+ IptCleanupAll(1);
+ spin_unlock(&PORTNETSCAN_SPINLOCK);
+ ipt_unregister_match(&ipt_portnetscan);
+
+
+}
+/*
+######################################################################################################################
+#### KernelInit ######################################################################################################
+######################################################################################################################
+*/
+module_init(init);
+module_exit(fini);
+#endif
+
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: patch: Port- and netscan detection for netfilter
2007-03-15 13:29 patch: Port- and netscan detection for netfilter Gladewitz, Robert (FH)
@ 2007-03-16 15:40 ` Patrick McHardy
2007-03-16 16:37 ` Tim Gardner
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Patrick McHardy @ 2007-03-16 15:40 UTC (permalink / raw)
To: Gladewitz, Robert (FH); +Cc: netfilter-devel
Gladewitz, Robert (FH) wrote:
> in my Master-Theses I designed a new kernel- and netfilter module for
> detection of net- and portscans. Now, the module is tested on more then
> 10 different firewall-installations. It's working without any problems
> during the last 8 months.
>
> Your can read the documentation on
> http://ipt-portnetscan.sourceforge.net/. There is also a possibility to
> download all versions of Kernel- and IpTables-Patches.
>
> I would be pleased to see you integrated these patches into IpTables of
> your use.
> Looking forward to your answer
Please attach patches inline so they can be read in the mail client.
> +++ linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt
> @@ -0,0 +1,389 @@
> +Allgemein Informationen zum Modul ipt_PORTNETSCAN
Luckily I speak german :)
But seriously, we already had different portscan-detection matches
submitted, but decided against merging them since its not clear
what the benefit of detecting scans is. It clearly doesn't improve
security since
- you can just scan slow enough not to be detected
- you don't need to scan to crack something
So all it offers is a bit of correlated information ("you were scanned
by ..."), that can also be extracted from log-files.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: patch: Port- and netscan detection for netfilter
2007-03-16 15:40 ` Patrick McHardy
@ 2007-03-16 16:37 ` Tim Gardner
2007-03-16 16:57 ` Patrick McHardy
2007-03-16 21:32 ` Jan Engelhardt
2007-03-16 21:29 ` Jan Engelhardt
2007-03-16 22:29 ` AW: " Gladewitz, Robert (FH)
2 siblings, 2 replies; 12+ messages in thread
From: Tim Gardner @ 2007-03-16 16:37 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Gladewitz, Robert (FH)
Patrick McHardy wrote:
> Gladewitz, Robert (FH) wrote:
>> in my Master-Theses I designed a new kernel- and netfilter module for
>> detection of net- and portscans. Now, the module is tested on more then
>> 10 different firewall-installations. It's working without any problems
>> during the last 8 months.
>>
>> Your can read the documentation on
>> http://ipt-portnetscan.sourceforge.net/. There is also a possibility to
>> download all versions of Kernel- and IpTables-Patches.
>>
>> I would be pleased to see you integrated these patches into IpTables of
>> your use.
>> Looking forward to your answer
>
> Please attach patches inline so they can be read in the mail client.
>
>> +++ linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt
>> @@ -0,0 +1,389 @@
>> +Allgemein Informationen zum Modul ipt_PORTNETSCAN
>
> Luckily I speak german :)
>
> But seriously, we already had different portscan-detection matches
> submitted, but decided against merging them since its not clear
> what the benefit of detecting scans is. It clearly doesn't improve
> security since
>
> - you can just scan slow enough not to be detected
> - you don't need to scan to crack something
>
> So all it offers is a bit of correlated information ("you were scanned
> by ..."), that can also be extracted from log-files.
>
>
Patrick,
One benefit of being able to block a port scanner is that it reduces or
stops the amount of ARP traffic that is generated. Depending on your
internal network design, lots of ARP traffic can have a significant
impact on WAN links and so on.
rtg
--
Tim Gardner timg@tpi.com www.tpi.com
OR 503-601-0234 x102 MT 406-443-5357
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: patch: Port- and netscan detection for netfilter
2007-03-16 16:37 ` Tim Gardner
@ 2007-03-16 16:57 ` Patrick McHardy
2007-03-16 21:32 ` Jan Engelhardt
1 sibling, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2007-03-16 16:57 UTC (permalink / raw)
To: Tim Gardner; +Cc: netfilter-devel, Gladewitz, Robert (FH)
Tim Gardner wrote:
> Patrick,
>
> One benefit of being able to block a port scanner is that it reduces or
> stops the amount of ARP traffic that is generated. Depending on your
> internal network design, lots of ARP traffic can have a significant
> impact on WAN links and so on.
Good point.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: patch: Port- and netscan detection for netfilter
2007-03-16 15:40 ` Patrick McHardy
2007-03-16 16:37 ` Tim Gardner
@ 2007-03-16 21:29 ` Jan Engelhardt
2007-03-16 22:29 ` AW: " Gladewitz, Robert (FH)
2 siblings, 0 replies; 12+ messages in thread
From: Jan Engelhardt @ 2007-03-16 21:29 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, Gladewitz, Robert (FH)
On Mar 16 2007 16:40, Patrick McHardy wrote:
>
>> +++ linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt
>> @@ -0,0 +1,389 @@
>> +Allgemein Informationen zum Modul ipt_PORTNETSCAN
If it's a match, make it lowercase.
>Luckily I speak german :)
Can't have that luxury.
>But seriously, we already had different portscan-detection matches
>submitted, but decided against merging them since its not clear
>what the benefit of detecting scans is. It clearly doesn't improve
>security since
>
>- you can just scan slow enough not to be detected
Speaking for chaostables, just have a look at section 9:
http://jengelh.hopto.org/p/chaostables/fw.html#se9
Either you scan so slowly that you do not get much of results, or you
scan fast enough that you are detected.
>- you don't need to scan to crack something
move port 22 to rand(0,65535) and a scan is needed first to figure out
where sshd is.
>diff -Naur linux-2.6.20.2.org/Documentation/ipt_PORTNETSCAN.txt linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt
>--- linux-2.6.20.2.org/Documentation/ipt_PORTNETSCAN.txt 1970-01-01 01:00:00.000000000 +0100
>+++ linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt 2007-03-10 14:33:15.000000000 +0100
>@@ -0,0 +1,389 @@
>+
>+--tree-depth [1|2|4|8|16|32]
>+Standard: --tree-depth 4
>+Diese Option gibt die Baumtiefe des Suchbaumes (Suchindex) (trace-tree /
>+berwachungsliste) an. Bei einer angegeben Baumtiefe von 1 wird eine
>+einfache verkettete Liste als Suchindex verwendet. Bei eigenen
>+Testreihen hat sich eine Baumtiefe von vier als Optimum herausgestellt.
>+Bei den Tests wurde aber von mehr als 1000 gleichzeitigen Verbindungen
>+ausgegangen.
>+
>+--trace-time [Sekunden] (10-3600)
>+Standard: --trace-time 120 (2 Minuten)
>+Die Option trace-time gibt die Zeit in Sekunden an, welche eine Quelladresse
>+berwacht wird. Solange Pakete durch die Regel berprft werden, beginnt
>+die berwachungszeit von neuem. Dies bedeutet, dass z.B. bei einem Wert von
>+20 in dieser Option der berwachungseintrag der Quelladresse erst dann
>+entfernt wird, wenn dieser 120 Sekunden keine Prfung mehr erfordert hat,
>+d.h. dass in dieser Zeitspanne kein Paket durch die IpTables Regel zur
>+berprfung an das Modul gesendet wurde. Dies ist in der Regel der Fall,
>+wenn der Rechner keine Verbindung mehr zum Zielsystem hat.
This sounds like -m recent --update ...
>+--block-time [Sekunden] (0-172800)
>+Standard: --block-time 3600 (1 Stunde)
>+Die Option block-time gibt die Zeit in Sekunden an, die die Quelladresse eines
>+Rechners gesperrt wird, falls eine der definierten Schwellwerte (Quotas)
>+erfllt ist. Der Rechner wird im Falle des berschreitens eines Schwellwertes
>+(Quota) aus den berwachten Eintrgen gelscht und in die Ablehnungsliste
>+verschoben. Diese Liste ist eine normale verkettete Liste im Speicher und
>+wird nicht zustzlich indiziert.
-m recent -j DROP
>+--clean-interval [Sekunden] (1-60)
>+Standard: --clean-interval 1 (1 Sekunde)
>+Diese Option legt das Intervall fest, nach dem veraltete Eintrge aus den
>+berwachungs- und Ablehnungslisten gelscht werden. Zustzlich ist im Kernel
>+noch ein globales Intervall festgelegt, nach dem veraltete Eintrge aller
>+Konfigurationsumgebungen freigegeben werden.
-m recent --seconds
>+--port-scan-quota [Quota] (3-1000)
>+Standard: --port-scan-quota 10
>+Diese Option legt fest, ab welchem Schwellwert (Quota) ein Portscan erkannt
>+wird.
>+Ein Portscan wird angenommen bei Erfllung folgender Voraussetzung:
>+(Zielports / Zieladressen) > port-scan-quota
Sounds like -m psd.
>+Informationen ber den Modulzustand im proc-Dateisystem
>+-------------------------------------------------------
Use sysfs.
>+// Unabhngige Typdefinitionen
/* */
>+// StandardDefinitionen
>+#define DEFAULTTREEDEPTH 4 /* StandardTiefe des verwendeten Baumes */
>+#define DEFAULTDEBUGLEVEL 0 /* Debuglevel */
>+#define DEFAULTTRACETIME 120 /* 10 Minuten berwachen per Default (600 Sekunden = 10 Minuten) */
>+#define MAXTRACETIME 3600 /* 1 Stunde Maximal berwachungszeit (3600 Sekunden = 1 Stunde) */
>+#define DEFAULTCLEANINTERVAL 1 /* Jede Sekunde soll geprft werden, ob Eintrge veraltet sind */
>+#define MAXTCLEANINTERVAL 60 /* Maxmialer Wert fr clean-interval */
>+#define MAXUINT32 4294967295 /* Maximaler 32 BIT Unsigned Int */
>+#define MAXENDNODEENTRY 9999 /* Maximale Lnge in Vektoren der Werte DPT und DST einer EndNode */
>+#define DEFAULTPORTSCANQUOTA 10 /* Portscan Erkennung: Standardwert fr Verhltnis (Schwellwert) von Zieladresse zu Zielport (Zielports/Zieladressen) */
>+#define MAXPORTSCANQUOTA 1000 /* Maximalwert fr Schwellwert zur Portscan Erkennung */
>+#define DEFAULTNETSCANQUOTA 10 /* Netscan Erkennung: Standardwert fr Verhltnis (Schwellwert) von Zielport zur Zieladresse (Zieladressen/Zielports) */
>+#define MAXNETSCANQUOTA 1000 /* Maximalwert fr Schwellwert zur Netscan Erkennung */
>+#define DEFAULTBLOCKTIME 3600 /* Zeit, die ein Host als blockiert gilt, falls ein Port- oder Netscan erkannt wird */
>+#define MAXBLOCKTIME 172800 /* Maximale Zeit fr blocken einer Quelladresse (172800 = 2 Tage) */
>+#define DEFAULTDENYLISTCOUNT 10 /* Default Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
>+#define MINDENYLISTCOUNT 10 /* Minimale Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
>+#define MAXDENYLISTCOUNT 2000 /* Maximale Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
>+#define MINENDNODECOUNT 10 /* Minimale Anzahl an berwachten Eintrgen */
>+#define MAXENDNODECOUNT 20000 /* Maximale Anzahl an berwachten Eintrgen */
>+#define DEFAULTENDNODECOUNT 10000 /* Standard Anzahl an berwachten Eintrgen */
>+#define GLOBALCLEANUP 30 /* Globaler Cleanup-Interval */
>+#define DEFAULTCOMBINEDQUOTA 50 /* Schwellwert fr Zielhost + Zielports eines Quellrechners */
>+#define MAXCOMBINEDQUOTA 1000 /* Maximaler Schwellwert fr Zielhost + Zielports eines Quellrechners */
>+#define KERNELLINEMAX 1024 /* Maximale Lnge einer Ausgabezeile fr den Kernel (proc-Aufruf) */
>+#define KERNELPAGESIZE 4096 /* Pagesize im Kernel */
>+#define DEFAULTCHECKDENYENTRIES 0 /* Nur Deny-Liste berprfen */
>+
>+// Erkannte Probleme
>+#define REASONPORTSCAN 1 /* Portscan wurde erkannt */
>+#define REASONNETSCAN 2 /* Netscan wurde erkannt */
>+#define REASONCOMPINED 4 /* Combined Scan wurde erkannt */
>+#define REASONUNKNOWN 1024
A ton of parameters you got there..
>+struct ipt_PORTNETSCAN_info
>+{
>+ unsigned int tree_depth;
>+ unsigned int trace_time;
>+ unsigned int clean_interval;
>+ unsigned int port_scan_quota;
>+ unsigned int net_scan_quota;
>+ unsigned int max_deny_entries;
>+ unsigned int max_trace_entries;
>+ unsigned int block_time;
>+ unsigned int combined_quota;
>+ unsigned short check_deny_entries;
>+};
>[...]
>+struct IptGlobalConfStruct
>+{
>+ struct PortNetscanEnv * FirstPortNetscan; // Speichert den ersten Konfigurationeintrag (Konfigurationsumgebung)
>+ struct KernelOutLinePuffer * FirstOutLine; // Kernelausgabeliste: Bei proc_read-Aufruf ist dies der Zeiger auf das erste Element der noch auszugebenen Liste
>+ struct KernelOutLinePuffer * LastPrintOutLine; // Kernelausgabeliste: Letztes ausgegebenes Elemet
>+ struct KernelOutLinePuffer * LastAddOutLine; // Kernelausgabeliste: Letztes hinzugefgtes Element
>+ unsigned int FailBuffer; // Kernelausgabeliste: Bei nicht ausreichenden Puffer, werden hier die Anzahl der bereits verarbeiteten Bytes angegeben
>+ unsigned int Conf_Count; // Anzahl der Konfigurationseintrge
>+ time_t LastCleanup; // Letzer globaler Aufrumablauf (Unix-Zeit)
>+};
Please adhere to CodingStyle ;-)
A lot of structures.
>+struct TreeNode
>+{
>+ struct TreeNode * Parent; // bergeordneter Eintrag in Suchbaum (NULL, wenn in oberster Ebene)
>+ void * Childs; // untergeordneter Eintrag
>+ struct TreeNode * Prior; // vorheriges Element in gleicher Hierachieebene (NULL, wenn erster Eintrag in Hierachieebene)
>+ struct TreeNode * Next; // nchstes Element in gleicher Hierachieebene (NULL, wenn letzer Eintrag)
>+ u_int32_t TreeValue; // Anteil an Suchbegriff
>+};
Use #include <linux/rbtree.h> instead of reinwhenting the wheel, perhaps.
>+ PORTNETSCAN is an iptables module for the detection of PORT-, NET
>+ and COMBINEDSCANS using quotas. The usage is described in the
>+ accompanying document located at Documentation/ipt_PORTNETSCAN.txt
What are netscans / combinedscans?
>+menu "IP: Netfilter Configuration"
>+ depends on INET && NETFILTER
>+
>+config NF_CONNTRACK_IPV4
>+ tristate "IPv4 connection tracking support (required for NAT)"
>+ depends on NF_CONNTRACK
!? No, this should not be here...
>+++ linux-2.6.20.2/net/ipv4/netfilter/Makefile.orig 2007-03-09 19:58:04.000000000 +0100
Should not be here.
>+int Kernel_CreateProcmemPuffer(void)
>+{
>+ // Functionsvariablen
>+ struct PortNetscanEnv * TEMP = IptGlobalConf.FirstPortNetscan;
>+ unsigned int COUNTER = 0;
>+ u_int32_t * IPPARTS = (u_int32_t*)_malloc( sizeof(u_int32_t) * 4, GFP_KERNEL);
>+ unsigned short PARTSIZE = 8; /* 32/4* */
>+ unsigned int TEXTLEN = 0;
>+ char STRINGBUFFER[KERNELLINEMAX];
>+
>+
>+ if (IptGlobalConf.FirstOutLine == NULL )
>+ {
>+
>+ spin_lock(&PORTNETSCAN_SPINLOCK);
>+
>+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"# IpTables PORTNETSCAN MODUL\n# --------------------------\n#\n");
>+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
>+
>+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"G\tCount_Global_Conf: %d\n",IptGlobalConf.Conf_Count);
>+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
>+
>+ snprintf(STRINGBUFFER,KERNELLINEMAX-1,"U\tUpdating_Time(Unix): %u\n#\n",(unsigned int)getunixtime());
>+ TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
Blargh. Also note that proc files are limited to PAGE_SIZE, which is most
likely exceeded with all this info.
Too much code (and too much unused or duplicate code) for what it does. We've
got ipt_psd (checking scans/time) for long enough, and recently chaostables
(checking connection behavior) joined the scene. I think we really exploited
all methods by now.
Jan
--
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: patch: Port- and netscan detection for netfilter
2007-03-16 16:37 ` Tim Gardner
2007-03-16 16:57 ` Patrick McHardy
@ 2007-03-16 21:32 ` Jan Engelhardt
2007-03-16 22:17 ` Gladewitz, Robert (FH)
1 sibling, 1 reply; 12+ messages in thread
From: Jan Engelhardt @ 2007-03-16 21:32 UTC (permalink / raw)
To: Tim Gardner; +Cc: netfilter-devel, Patrick McHardy, Gladewitz, Robert (FH)
On Mar 16 2007 10:37, Tim Gardner wrote:
>
>One benefit of being able to block a port scanner is that it reduces or
>stops the amount of ARP traffic that is generated. Depending on your
>internal network design, lots of ARP traffic can have a significant
>impact on WAN links and so on.
ARP traffic is hardly a problem when the attacker is at least two hops away
(which is always true in the Internet except when your own ISP pokes on you) or
there is a NOARP link at hop 1 (as is the case with PPP/etc.).
Jan
--
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: patch: Port- and netscan detection for netfilter
2007-03-16 21:32 ` Jan Engelhardt
@ 2007-03-16 22:17 ` Gladewitz, Robert (FH)
2007-03-17 0:37 ` Jan Engelhardt
0 siblings, 1 reply; 12+ messages in thread
From: Gladewitz, Robert (FH) @ 2007-03-16 22:17 UTC (permalink / raw)
To: netfilter-devel
The interesting is the additional functionality in this module. If a host has identifying as portscan-source you can define a time for matching the rules after the first identification. For example, you can drop all packages for a time xxx from this host after identifying as portscan-source. In this cast, the attackers can't find more information about your network.
Robert
-----Ursprüngliche Nachricht-----
Von: netfilter-devel-bounces@lists.netfilter.org [mailto:netfilter-devel-bounces@lists.netfilter.org] Im Auftrag von Jan Engelhardt
Gesendet: Freitag, 16. März 2007 22:32
An: Tim Gardner
Cc: netfilter-devel@lists.netfilter.org; Patrick McHardy; Gladewitz, Robert (FH)
Betreff: Re: patch: Port- and netscan detection for netfilter
On Mar 16 2007 10:37, Tim Gardner wrote:
>
>One benefit of being able to block a port scanner is that it reduces or
>stops the amount of ARP traffic that is generated. Depending on your
>internal network design, lots of ARP traffic can have a significant
>impact on WAN links and so on.
ARP traffic is hardly a problem when the attacker is at least two hops away
(which is always true in the Internet except when your own ISP pokes on you) or
there is a NOARP link at hop 1 (as is the case with PPP/etc.).
Jan
--
^ permalink raw reply [flat|nested] 12+ messages in thread
* AW: patch: Port- and netscan detection for netfilter
2007-03-16 15:40 ` Patrick McHardy
2007-03-16 16:37 ` Tim Gardner
2007-03-16 21:29 ` Jan Engelhardt
@ 2007-03-16 22:29 ` Gladewitz, Robert (FH)
2007-03-19 4:59 ` Patrick McHardy
2 siblings, 1 reply; 12+ messages in thread
From: Gladewitz, Robert (FH) @ 2007-03-16 22:29 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel
The problem is, on the most attacks, the hacker try to get some information on the network. This module implements 3 different situations:
- Netscan (Scan more hosts on less ports)
- Portscan (Scan less Hosts and many ports)
- Combined Scan (Scan many Ports on many)
On the testing-systems we can see, that the attacs to different service will be less then before! The interesting thing is, that no more attacks on unknown services are happens.
The Portscan is only the one side - the other side is, that the source can be blocked on a defined time - please read the documentation ipt-portscan.sourceforge.net.
LG
Robert
-----Ursprüngliche Nachricht-----
Von: netfilter-devel-bounces@lists.netfilter.org [mailto:netfilter-devel-bounces@lists.netfilter.org] Im Auftrag von Patrick McHardy
Gesendet: Freitag, 16. März 2007 16:41
An: Gladewitz, Robert (FH)
Cc: netfilter-devel@lists.netfilter.org
Betreff: Re: patch: Port- and netscan detection for netfilter
Gladewitz, Robert (FH) wrote:
> in my Master-Theses I designed a new kernel- and netfilter module for
> detection of net- and portscans. Now, the module is tested on more then
> 10 different firewall-installations. It's working without any problems
> during the last 8 months.
>
> Your can read the documentation on
> http://ipt-portnetscan.sourceforge.net/. There is also a possibility to
> download all versions of Kernel- and IpTables-Patches.
>
> I would be pleased to see you integrated these patches into IpTables of
> your use.
> Looking forward to your answer
Please attach patches inline so they can be read in the mail client.
> +++ linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt
> @@ -0,0 +1,389 @@
> +Allgemein Informationen zum Modul ipt_PORTNETSCAN
Luckily I speak german :)
But seriously, we already had different portscan-detection matches
submitted, but decided against merging them since its not clear
what the benefit of detecting scans is. It clearly doesn't improve
security since
- you can just scan slow enough not to be detected
- you don't need to scan to crack something
So all it offers is a bit of correlated information ("you were scanned
by ..."), that can also be extracted from log-files.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: patch: Port- and netscan detection for netfilter
2007-03-16 22:17 ` Gladewitz, Robert (FH)
@ 2007-03-17 0:37 ` Jan Engelhardt
0 siblings, 0 replies; 12+ messages in thread
From: Jan Engelhardt @ 2007-03-17 0:37 UTC (permalink / raw)
To: Gladewitz, Robert (FH); +Cc: netfilter-devel
On Mar 16 2007 23:17, Gladewitz, Robert (FH) wrote:
>
>The interesting is the additional functionality in this module. If a
>host has identifying as portscan-source you can define a time for
>matching the rules after the first identification. For example, you can
>drop all packages for a time xxx from this host after identifying as
>portscan-source. In this cast, the attackers can't find more
>information about your network.
Now, again for the list, what can its timing code do better than, say,
-A INPUT -m portnetscan -m recent --name evil --set;
-A INPUT -m recent --evil --update --seconds xxx -j DROP;
Jan
--
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AW: patch: Port- and netscan detection for netfilter
2007-03-16 22:29 ` AW: " Gladewitz, Robert (FH)
@ 2007-03-19 4:59 ` Patrick McHardy
2007-03-19 13:12 ` AW: " Gladewitz, Robert (FH)
0 siblings, 1 reply; 12+ messages in thread
From: Patrick McHardy @ 2007-03-19 4:59 UTC (permalink / raw)
To: Gladewitz, Robert (FH); +Cc: netfilter-devel
Gladewitz, Robert (FH) wrote:
> The problem is, on the most attacks, the hacker try to get some information on the network. This module implements 3 different situations:
Putting aside the question of the usefulness of this, whats the
difference to using the three rules below?
> - Netscan (Scan more hosts on less ports)
iptables -A PREROUTING -m state --state NEW \
-m hashlimit --hashlimit-name netscan \
--hashlimit-mode dstip \
--hashlimit n/sec \
-j DROP
> - Portscan (Scan less Hosts and many ports)
iptables -A PREROUTING -m state --state NEW \
-m hashlimit --hashlimit-name portscan \
--hashlimit-mode dstport \
--hashlimit n/sec \
-j DROP
> - Combined Scan (Scan many Ports on many)
iptables -A PREROUTING -m state --state NEW \
-m hashlimit --hashlimit-name portnetscan \
--hashlimit-mode dstip,dstport \
--hashlimit n/sec \
-j DROP
^ permalink raw reply [flat|nested] 12+ messages in thread
* AW: AW: patch: Port- and netscan detection for netfilter
2007-03-19 4:59 ` Patrick McHardy
@ 2007-03-19 13:12 ` Gladewitz, Robert (FH)
2007-03-20 16:30 ` Jan Engelhardt
0 siblings, 1 reply; 12+ messages in thread
From: Gladewitz, Robert (FH) @ 2007-03-19 13:12 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel
Hello Patrick,
This module is not designed for using as locally firewall, it is designed for router in networks with dmz. For this, all connection is saved in an tree-structure. Internal, I look for all Connection the rule sends to check. (Look at the time background) If the module have same connection (source - Destination) the the module decide on following rules (positive or false answered -from -m). For this, the module saves source-ip, dest-ip and dest-port.
Definition: netscan for source address is recognized when:
----------------------------------------------------------
(number of destination hosts / number of destination ports) \
> Defined threshold value (quota) for netscan
Definition: portscan for source address is recognized when:
----------------------------------------------------------
(number of destination ports / number of destination hosts) \
> Defined quota for portscan
Definition: combined-scan for source address is recognized when:
----------------------------------------------------------
(number of destination ports / number of destination hosts) \
> Defined threshold value (quota) for combined scan
For all actions your can be sure, that a port- or netscan is be happening, not only less / many - port / hosts!! The module can be sure deside, that the many dest-port (for axamlpe) comes from this source-host!
Please read the documentation /and or source - it is completely different to all other modules. The Idea is, that your look for all connection, which are match by the rule - the state is totally uninteresting.
If a source-host is identified as a scan-host you can drop the all packages from dir source-ip for a defined time. The interesting is also, that you can use it for DROP-Packet on the end of all rules also (In the documentation I have defined 2 sceneries). On the start of the rules, your have only a check-line - on the end of all rules, you test if the client have to much denied traffic - then you can drop all package up this time.
The next is, your can check the state of connections and DENY-Hosts in /proc/net/stat/portnetscan
For the future, I planed a detection of Bot-Net-Scans.
Cu
Robert
-----Ursprüngliche Nachricht-----
Von: Patrick McHardy [mailto:kaber@trash.net]
Gesendet: Montag, 19. März 2007 05:59
An: Gladewitz, Robert (FH)
Cc: netfilter-devel@lists.netfilter.org
Betreff: Re: AW: patch: Port- and netscan detection for netfilter
Gladewitz, Robert (FH) wrote:
> The problem is, on the most attacks, the hacker try to get some information on the network. This module implements 3 different situations:
Putting aside the question of the usefulness of this, whats the
difference to using the three rules below?
> - Netscan (Scan more hosts on less ports)
iptables -A PREROUTING -m state --state NEW \
-m hashlimit --hashlimit-name netscan \
--hashlimit-mode dstip \
--hashlimit n/sec \
-j DROP
> - Portscan (Scan less Hosts and many ports)
iptables -A PREROUTING -m state --state NEW \
-m hashlimit --hashlimit-name portscan \
--hashlimit-mode dstport \
--hashlimit n/sec \
-j DROP
> - Combined Scan (Scan many Ports on many)
iptables -A PREROUTING -m state --state NEW \
-m hashlimit --hashlimit-name portnetscan \
--hashlimit-mode dstip,dstport \
--hashlimit n/sec \
-j DROP
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AW: AW: patch: Port- and netscan detection for netfilter
2007-03-19 13:12 ` AW: " Gladewitz, Robert (FH)
@ 2007-03-20 16:30 ` Jan Engelhardt
0 siblings, 0 replies; 12+ messages in thread
From: Jan Engelhardt @ 2007-03-20 16:30 UTC (permalink / raw)
To: Gladewitz, Robert (FH); +Cc: netfilter-devel, Patrick McHardy
On Mar 19 2007 14:12, Gladewitz, Robert (FH) wrote:
>
>This module is not designed for using as locally firewall, it is designed
>for router in networks with dmz.
Who said -m hashlimit/-m recent was limited to a local firewall?
>For all actions your can be sure, that a port- or netscan is be
>happening, not only less / many - port / hosts!! The module can be sure
>deside, that the many dest-port (for axamlpe) comes from this
>source-host!
Do yourself a favor: Add a rule -m hashlimit --hashlimit-mode srcip,dstip
to your router (not 'local firewall') and do a portscan. Watch the
iptables -nvL counters on that rule rise.
>Please read the documentation /and or source - it is completely different
>to all other modules. The Idea is, that your look for all connection,
>which are match by the rule - the state is totally uninteresting.
The state _is_ interesting. Because ESTABLISHED connections are, with the
exception of Connect and Grab scans [ct], always "good" ones, i.e. the
firewall cannot decide, with the exception of [l7] and [l7] is also more
like [l5], if traffic is good or evil.
>
>If a source-host is identified as a scan-host you can drop the all
>packages from dir source-ip for a defined time.
You fail to explain, given that we know a certain host is "evil", why -m
recent cannot be used to drop its evil packets.
>The interesting is also, that you can use it for DROP-Packet on the end
>of all rules also (In the documentation I have defined 2 sceneries). On
>the start of the rules, your have only a check-line - on the end of all
>rules, you test if the client have to much denied traffic - then you can
>drop all package up this time.
Your check line is equivalent to -m recent --rcheck/--update.
The one at the end of the rules is eqv. to -m recent --set.
>The next is, your can check the state of connections and DENY-Hosts in
>/proc/net/stat/portnetscan
(And ipt_recent has also its own proc file for listing denied/matched hosts)
>-----Ursprüngliche Nachricht-----
>Von: Patrick McHardy [mailto:kaber@trash.net]
>Gesendet: Montag, 19. März 2007 05:59
>An: Gladewitz, Robert (FH)
>Cc: netfilter-devel@lists.netfilter.org
>Betreff: Re: AW: patch: Port- and netscan detection for netfilter
>
>Gladewitz, Robert (FH) wrote:
>> The problem is, on the most attacks, the hacker try to get some information on the network. This module implements 3 different situations:
>
>Putting aside the question of the usefulness of this, whats the
>difference to using the three rules below?
>
>> - Netscan (Scan more hosts on less ports)
>
>iptables -A PREROUTING -m state --state NEW \
> -m hashlimit --hashlimit-name netscan \
> --hashlimit-mode dstip \
> --hashlimit n/sec \
> -j DROP
>
>> - Portscan (Scan less Hosts and many ports)
>
>iptables -A PREROUTING -m state --state NEW \
> -m hashlimit --hashlimit-name portscan \
> --hashlimit-mode dstport \
> --hashlimit n/sec \
> -j DROP
>
>> - Combined Scan (Scan many Ports on many)
>
>iptables -A PREROUTING -m state --state NEW \
> -m hashlimit --hashlimit-name portnetscan \
> --hashlimit-mode dstip,dstport \
> --hashlimit n/sec \
> -j DROP
>
>
>
Jan
--
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2007-03-20 16:30 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-15 13:29 patch: Port- and netscan detection for netfilter Gladewitz, Robert (FH)
2007-03-16 15:40 ` Patrick McHardy
2007-03-16 16:37 ` Tim Gardner
2007-03-16 16:57 ` Patrick McHardy
2007-03-16 21:32 ` Jan Engelhardt
2007-03-16 22:17 ` Gladewitz, Robert (FH)
2007-03-17 0:37 ` Jan Engelhardt
2007-03-16 21:29 ` Jan Engelhardt
2007-03-16 22:29 ` AW: " Gladewitz, Robert (FH)
2007-03-19 4:59 ` Patrick McHardy
2007-03-19 13:12 ` AW: " Gladewitz, Robert (FH)
2007-03-20 16:30 ` Jan Engelhardt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.