mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-06 20:55:13 +02:00
Import Chaostables extensions
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
This commit is contained in:
@@ -5,8 +5,11 @@ include ${XA_TOPSRCDIR}/mconfig
|
||||
|
||||
obj-m += compat_xtables.o
|
||||
|
||||
obj-${build_CHAOS} += xt_CHAOS.o
|
||||
obj-${build_DELUDE} += xt_DELUDE.o
|
||||
obj-${build_LOGMARK} += xt_LOGMARK.o
|
||||
obj-${build_TARPIT} += xt_TARPIT.o
|
||||
obj-${build_TEE} += xt_TEE.o
|
||||
obj-${build_portscan} += xt_portscan.o
|
||||
|
||||
-include ${M}/*.Kbuild
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_arp.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/route.h>
|
||||
#include "compat_xtnu.h"
|
||||
@@ -228,6 +229,25 @@ void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
|
||||
EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
|
||||
#endif
|
||||
|
||||
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
|
||||
uint8_t revision)
|
||||
{
|
||||
static const char *const xt_prefix[] = {
|
||||
[AF_INET] = "ip",
|
||||
[AF_INET6] = "ip6",
|
||||
[NF_ARP] = "arp",
|
||||
};
|
||||
struct xt_match *match;
|
||||
|
||||
match = try_then_request_module(xt_find_match(af, name, revision),
|
||||
"%st_%s", xt_prefix[af], name);
|
||||
if (IS_ERR(match) || match == NULL)
|
||||
return NULL;
|
||||
|
||||
return match;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_request_find_match);
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
int xtnu_ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type)
|
||||
{
|
||||
|
@@ -13,11 +13,18 @@
|
||||
# define NF_INET_FORWARD NF_IP_FORWARD
|
||||
# define NF_INET_LOCAL_OUT NF_IP_LOCAL_OUT
|
||||
# define NF_INET_POST_ROUTING NF_IP_POST_ROUTING
|
||||
# define init_net xtnu_ip_route_output_key /* yes */
|
||||
# define ip_local_out xtnu_ip_local_out
|
||||
# define ip_route_output_key xtnu_ip_route_output_key
|
||||
# include "compat_nfinetaddr.h"
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
# define init_net xtnu_ip_route_output_key /* yes */
|
||||
# define init_net__loopback_dev (&loopback_dev)
|
||||
#else
|
||||
# define init_net__loopback_dev init_net.loopback_dev
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 22)
|
||||
# define xt_match xtnu_match
|
||||
# define xt_register_match xtnu_register_match
|
||||
@@ -35,6 +42,7 @@
|
||||
# define xt_unregister_targets xtnu_unregister_targets
|
||||
#endif
|
||||
|
||||
#define xt_request_find_match xtnu_request_find_match
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
#endif /* _XTABLES_COMPAT_H */
|
||||
|
@@ -61,6 +61,7 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
|
||||
return q;
|
||||
}
|
||||
|
||||
extern int xtnu_ip_local_out(struct sk_buff *);
|
||||
extern int xtnu_ip_route_me_harder(struct sk_buff *, unsigned int);
|
||||
extern int xtnu_register_match(struct xtnu_match *);
|
||||
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
|
||||
@@ -71,5 +72,7 @@ extern int xtnu_register_target(struct xtnu_target *);
|
||||
extern void xtnu_unregister_target(struct xtnu_target *);
|
||||
extern int xtnu_register_targets(struct xtnu_target *, unsigned int);
|
||||
extern void xtnu_unregister_targets(struct xtnu_target *, unsigned int);
|
||||
extern struct xt_match *xtnu_request_find_match(unsigned int,
|
||||
const char *, uint8_t);
|
||||
|
||||
#endif /* _COMPAT_XTNU_H */
|
||||
|
113
extensions/libxt_CHAOS.c
Normal file
113
extensions/libxt_CHAOS.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* CHAOS target for Xtables
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_CHAOS.h"
|
||||
|
||||
enum {
|
||||
F_DELUDE = 1 << 0,
|
||||
F_TARPIT = 1 << 1,
|
||||
};
|
||||
|
||||
static const struct option chaos_tg_opts[] = {
|
||||
{.name = "delude", .has_arg = false, .val = 'd'},
|
||||
{.name = "tarpit", .has_arg = false, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void chaos_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"CHAOS target options:\n"
|
||||
" --delude Enable DELUDE processing for TCP\n"
|
||||
" --tarpit Enable TARPIT processing for TCP\n");
|
||||
}
|
||||
|
||||
static int chaos_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_chaos_tginfo *info = (void *)((*target)->data);
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
info->variant = XTCHAOS_DELUDE;
|
||||
*flags |= F_DELUDE;
|
||||
return true;
|
||||
case 't':
|
||||
info->variant = XTCHAOS_TARPIT;
|
||||
*flags |= F_TARPIT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void chaos_tg_check(unsigned int flags)
|
||||
{
|
||||
if (flags == (F_DELUDE | F_TARPIT))
|
||||
/* If flags == 0x03, both were specified, which should not be. */
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"CHAOS: only one of --tarpit or --delude "
|
||||
"may be specified");
|
||||
}
|
||||
|
||||
static void chaos_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target, int numeric)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTCHAOS_DELUDE:
|
||||
printf("DELUDE ");
|
||||
break;
|
||||
case XTCHAOS_TARPIT:
|
||||
printf("TARPIT ");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTCHAOS_DELUDE:
|
||||
printf("--delude ");
|
||||
break;
|
||||
case XTCHAOS_TARPIT:
|
||||
printf("--tarpit ");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static struct xtables_target chaos_tg_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.name = "CHAOS",
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.help = chaos_tg_help,
|
||||
.parse = chaos_tg_parse,
|
||||
.final_check = chaos_tg_check,
|
||||
.print = chaos_tg_print,
|
||||
.save = chaos_tg_save,
|
||||
.extra_opts = chaos_tg_opts,
|
||||
};
|
||||
|
||||
void _init(void);
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&chaos_tg_reg);
|
||||
}
|
18
extensions/libxt_CHAOS.man
Normal file
18
extensions/libxt_CHAOS.man
Normal file
@@ -0,0 +1,18 @@
|
||||
+Causes confusion on the other end by doing odd things with incoming packets.
|
||||
+CHAOS will randomly reply (or not) with one of its configurable subtargets:
|
||||
+.TP
|
||||
+\fB--delude\fR
|
||||
+Use the REJECT and DELUDE targets as a base to do a sudden or deferred
|
||||
+connection reset, fooling some network scanners to return non-deterministic
|
||||
+(randomly open/closed) results, and in case it is deemed open, it is actually
|
||||
+closed/filtered.
|
||||
+.TP
|
||||
+\fB--tarpit\fR
|
||||
+Use the REJECT and TARPIT target as a base to hold the connection until it
|
||||
+times out. This consumes conntrack entries when connection tracking is loaded
|
||||
+(which usually is on most machines), and routers inbetween you and the Internet
|
||||
+may fail to do their connection tracking if they have to handle more
|
||||
+connections than they can.
|
||||
+.PP
|
||||
+The randomness factor of not replying vs. replying can be set during load-time
|
||||
+of the xt_CHAOS module or during runtime in /sys/modules/xt_CHAOS/parameters.
|
47
extensions/libxt_DELUDE.c
Normal file
47
extensions/libxt_DELUDE.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* DELUDE target for Xtables
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
static void delude_tg_help(void)
|
||||
{
|
||||
printf("DELUDE takes no options\n");
|
||||
}
|
||||
|
||||
static int delude_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void delude_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target delude_tg_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.name = "DELUDE",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.help = delude_tg_help,
|
||||
.parse = delude_tg_parse,
|
||||
.final_check = delude_tg_check,
|
||||
};
|
||||
|
||||
void _init(void);
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&delude_tg_reg);
|
||||
}
|
4
extensions/libxt_DELUDE.man
Normal file
4
extensions/libxt_DELUDE.man
Normal file
@@ -0,0 +1,4 @@
|
||||
The DELUDE target will reply to a SYN packet with SYN-ACK, and to all other
|
||||
packets with an RST. This will terminate the connection much like REJECT, but
|
||||
network scanners doing TCP half-open discovery can be spoofed to make them
|
||||
belive the port is open rather than closed/filtered.
|
121
extensions/libxt_portscan.c
Normal file
121
extensions/libxt_portscan.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* portscan target for Xtables
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_portscan.h"
|
||||
|
||||
static const struct option portscan_mt_opts[] = {
|
||||
{.name = "stealth", .has_arg = false, .val = 'x'},
|
||||
{.name = "synscan", .has_arg = false, .val = 's'},
|
||||
{.name = "cnscan", .has_arg = false, .val = 'c'},
|
||||
{.name = "grscan", .has_arg = false, .val = 'g'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void portscan_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"portscan match options:\n"
|
||||
"(Combining them will make them match by OR-logic)\n"
|
||||
" --stealth Match TCP Stealth packets\n"
|
||||
" --synscan Match TCP SYN scans\n"
|
||||
" --cnscan Match TCP Connect scans\n"
|
||||
" --grscan Match Banner Grabbing scans\n");
|
||||
}
|
||||
|
||||
static int portscan_mt_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_portscan_mtinfo *info = (void *)((*match)->data);
|
||||
|
||||
switch (c) {
|
||||
case 'c':
|
||||
info->match_cn = true;
|
||||
return true;
|
||||
case 'g':
|
||||
info->match_gr = true;
|
||||
return true;
|
||||
case 's':
|
||||
info->match_syn = true;
|
||||
return true;
|
||||
case 'x':
|
||||
info->match_stealth = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void portscan_mt_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void portscan_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = (const void *)(match->data);
|
||||
const char *s = "";
|
||||
|
||||
printf("portscan ");
|
||||
if (info->match_stealth) {
|
||||
printf("STEALTH");
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_syn) {
|
||||
printf("%sSYNSCAN", s);
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_cn) {
|
||||
printf("%sCNSCAN", s);
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_gr)
|
||||
printf("%sGRSCAN", s);
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void portscan_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = (const void *)(match->data);
|
||||
|
||||
if (info->match_stealth)
|
||||
printf("--stealth ");
|
||||
if (info->match_syn)
|
||||
printf("--synscan ");
|
||||
if (info->match_cn)
|
||||
printf("--cnscan ");
|
||||
if (info->match_gr)
|
||||
printf("--grscan ");
|
||||
}
|
||||
|
||||
static struct xtables_match portscan_mt_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.name = "portscan",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_portscan_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_portscan_mtinfo)),
|
||||
.help = portscan_mt_help,
|
||||
.parse = portscan_mt_parse,
|
||||
.final_check = portscan_mt_check,
|
||||
.print = portscan_mt_print,
|
||||
.save = portscan_mt_save,
|
||||
.extra_opts = portscan_mt_opts,
|
||||
};
|
||||
|
||||
void _init(void);
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&portscan_mt_reg);
|
||||
}
|
27
extensions/libxt_portscan.man
Normal file
27
extensions/libxt_portscan.man
Normal file
@@ -0,0 +1,27 @@
|
||||
Detects simple port scan attemps based upon the packet's contents. (This is
|
||||
different from other implementations, which also try to match the rate of new
|
||||
connections.) Note that an attempt is only discovered after it has been carried
|
||||
out, but this information can be used in conjunction with other rules to block
|
||||
the remote host's future connections. So this match module will match on the
|
||||
(probably) last packet the remote side will send to your machine.
|
||||
.TP
|
||||
\fB--stealth\fR
|
||||
Match if the packet did not belong to any known TCP connection
|
||||
(Stealth/FIN/XMAS/NULL scan).
|
||||
.TP
|
||||
\fB--synscan\fR
|
||||
Match if the connection was a TCP half-open discovery (SYN scan), i.e. the
|
||||
connection was torn down after the 2nd packet in the 3-way handshake.
|
||||
.TP
|
||||
\fB--cnscan\fR
|
||||
Match if the connection was a TCP full open discovery (connect scan), i.e. the
|
||||
connection was torn down after completion of the 3-way handshake.
|
||||
.TP
|
||||
\fB--grscan\fR
|
||||
Match if data in the connection only flew in the direction of the remote side,
|
||||
e.g. if the connection was terminated after a locally running daemon sent its
|
||||
identification. (e.g. openssh)
|
||||
.PP
|
||||
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
|
||||
so be advised to carefully use xt_portscan in conjunction with blocking rules,
|
||||
as it may lock out your very own internal network.
|
205
extensions/xt_CHAOS.c
Normal file
205
extensions/xt_CHAOS.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* CHAOS target for netfilter
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2007
|
||||
* Contact: Jan Engelhardt <jengelh@computergmbh.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/icmp.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_tcpudp.h>
|
||||
#include <linux/netfilter_ipv4/ipt_REJECT.h>
|
||||
#include <net/ip.h>
|
||||
#include "xt_CHAOS.h"
|
||||
static struct xt_match *xm_tcp;
|
||||
static struct xt_target *xt_delude, *xt_reject, *xt_tarpit;
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
/* Module parameters */
|
||||
static unsigned int reject_percentage = ~0U * .01;
|
||||
static unsigned int delude_percentage = ~0U * .0101;
|
||||
module_param(reject_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(delude_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
|
||||
/* References to other matches/targets */
|
||||
|
||||
static int have_delude, have_tarpit;
|
||||
|
||||
/* Static data for other matches/targets */
|
||||
static const struct ipt_reject_info reject_params = {
|
||||
.with = ICMP_HOST_UNREACH,
|
||||
};
|
||||
|
||||
static const struct xt_tcp tcp_params = {
|
||||
.spts = {0, ~0},
|
||||
.dpts = {0, ~0},
|
||||
};
|
||||
|
||||
/* CHAOS functions */
|
||||
static void xt_chaos_total(const struct xt_chaos_tginfo *info,
|
||||
struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
const int protoff = 4 * iph->ihl;
|
||||
const int offset = ntohs(iph->frag_off) & IP_OFFSET;
|
||||
typeof(xt_tarpit) destiny;
|
||||
bool ret;
|
||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 22)
|
||||
int hotdrop = false;
|
||||
#else
|
||||
bool hotdrop = false;
|
||||
#endif
|
||||
|
||||
ret = xm_tcp->match(skb, in, out, xm_tcp, &tcp_params,
|
||||
offset, protoff, &hotdrop);
|
||||
if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
|
||||
return;
|
||||
|
||||
destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
destiny->target(&skb, in, out, hooknum, destiny, NULL);
|
||||
#else
|
||||
destiny->target(skb, in, out, hooknum, destiny, NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
/*
|
||||
* Equivalent to:
|
||||
* -A chaos -m statistic --mode random --probability \
|
||||
* $reject_percentage -j REJECT --reject-with host-unreach;
|
||||
* -A chaos -p tcp -m statistic --mode random --probability \
|
||||
* $delude_percentage -j DELUDE;
|
||||
* -A chaos -j DROP;
|
||||
*/
|
||||
const struct xt_chaos_tginfo *info = targinfo;
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
if ((unsigned int)net_random() <= reject_percentage)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
return xt_reject->target(&skb, in, out, hooknum,
|
||||
target->__compat_target, &reject_params);
|
||||
#else
|
||||
return xt_reject->target(skb, in, out, hooknum, target,
|
||||
&reject_params);
|
||||
#endif
|
||||
|
||||
/* TARPIT/DELUDE may not be called from the OUTPUT chain */
|
||||
if (iph->protocol == IPPROTO_TCP &&
|
||||
info->variant != XTCHAOS_NORMAL && hooknum != NF_INET_LOCAL_OUT)
|
||||
xt_chaos_total(info, skb, in, out, hooknum);
|
||||
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static bool chaos_tg_check(const char *tablename, const void *entry,
|
||||
const struct xt_target *target, void *targinfo, unsigned int hook_mask)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = targinfo;
|
||||
|
||||
if (info->variant == XTCHAOS_DELUDE && !have_delude) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --delude when "
|
||||
"DELUDE module not available\n");
|
||||
return false;
|
||||
}
|
||||
if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "
|
||||
"TARPIT module not available\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct xt_target chaos_tg_reg = {
|
||||
.name = "CHAOS",
|
||||
.family = AF_INET,
|
||||
.table = "filter",
|
||||
.hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
|
||||
(1 << NF_INET_LOCAL_OUT),
|
||||
.target = chaos_tg,
|
||||
.checkentry = chaos_tg_check,
|
||||
.targetsize = sizeof(struct xt_chaos_tginfo),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init chaos_tg_init(void)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
xm_tcp = xt_request_find_match(AF_INET, "tcp", 0);
|
||||
if (xm_tcp == NULL) {
|
||||
printk(KERN_WARNING PFX "Error: Could not find or load "
|
||||
"\"tcp\" match\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
xt_reject = xt_request_find_target(AF_INET, "REJECT", 0);
|
||||
if (xt_reject == NULL) {
|
||||
printk(KERN_WARNING PFX "Error: Could not find or load "
|
||||
"\"REJECT\" target\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
xt_tarpit = xt_request_find_target(AF_INET, "TARPIT", 0);
|
||||
have_tarpit = xt_tarpit != NULL;
|
||||
if (!have_tarpit)
|
||||
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
||||
"\"TARPIT\" target\n");
|
||||
|
||||
xt_delude = xt_request_find_target(AF_INET, "DELUDE", 0);
|
||||
have_delude = xt_delude != NULL;
|
||||
if (!have_delude)
|
||||
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
||||
"\"DELUDE\" target\n");
|
||||
|
||||
if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {
|
||||
printk(KERN_WARNING PFX "xt_register_target returned "
|
||||
"error %d\n", ret);
|
||||
goto out3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out3:
|
||||
if (have_delude)
|
||||
module_put(xt_delude->me);
|
||||
if (have_tarpit)
|
||||
module_put(xt_tarpit->me);
|
||||
module_put(xt_reject->me);
|
||||
out2:
|
||||
module_put(xm_tcp->me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit chaos_tg_exit(void)
|
||||
{
|
||||
xt_unregister_target(&chaos_tg_reg);
|
||||
module_put(xm_tcp->me);
|
||||
module_put(xt_reject->me);
|
||||
if (have_delude)
|
||||
module_put(xt_delude->me);
|
||||
if (have_tarpit)
|
||||
module_put(xt_tarpit->me);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(chaos_tg_init);
|
||||
module_exit(chaos_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_CHAOS");
|
14
extensions/xt_CHAOS.h
Normal file
14
extensions/xt_CHAOS.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_CHAOS_H
|
||||
#define _LINUX_NETFILTER_XT_CHAOS_H 1
|
||||
|
||||
enum xt_chaos_target_variant {
|
||||
XTCHAOS_NORMAL,
|
||||
XTCHAOS_TARPIT,
|
||||
XTCHAOS_DELUDE,
|
||||
};
|
||||
|
||||
struct xt_chaos_tginfo {
|
||||
uint8_t variant;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_CHAOS_H */
|
175
extensions/xt_DELUDE.c
Normal file
175
extensions/xt_DELUDE.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* DELUDE target
|
||||
* Copyright © CC Computer Consultants GmbH, 2007 - 2008
|
||||
*
|
||||
* Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
|
||||
* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
# include <linux/netfilter_bridge.h>
|
||||
#endif
|
||||
#include <net/tcp.h>
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
||||
{
|
||||
struct tcphdr _otcph, *tcph;
|
||||
const struct tcphdr *oth;
|
||||
const struct iphdr *oiph;
|
||||
unsigned int addr_type;
|
||||
struct sk_buff *nskb;
|
||||
struct iphdr *niph;
|
||||
|
||||
oiph = ip_hdr(oldskb);
|
||||
|
||||
/* IP header checks: fragment. */
|
||||
if (oiph->frag_off & htons(IP_OFFSET))
|
||||
return;
|
||||
|
||||
oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
|
||||
sizeof(_otcph), &_otcph);
|
||||
if (oth == NULL)
|
||||
return;
|
||||
|
||||
/* No RST for RST. */
|
||||
if (oth->rst)
|
||||
return;
|
||||
|
||||
/* Check checksum */
|
||||
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
||||
return;
|
||||
|
||||
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
||||
LL_MAX_HEADER, GFP_ATOMIC);
|
||||
if (nskb == NULL)
|
||||
return;
|
||||
|
||||
skb_reserve(nskb, LL_MAX_HEADER);
|
||||
skb_reset_network_header(nskb);
|
||||
niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
|
||||
niph->version = 4;
|
||||
niph->ihl = sizeof(struct iphdr) / 4;
|
||||
niph->tos = 0;
|
||||
niph->id = 0;
|
||||
niph->frag_off = htons(IP_DF);
|
||||
niph->protocol = IPPROTO_TCP;
|
||||
niph->check = 0;
|
||||
niph->saddr = oiph->daddr;
|
||||
niph->daddr = oiph->saddr;
|
||||
|
||||
tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
|
||||
memset(tcph, 0, sizeof(*tcph));
|
||||
tcph->source = oth->dest;
|
||||
tcph->dest = oth->source;
|
||||
tcph->doff = sizeof(struct tcphdr) / 4;
|
||||
|
||||
/* DELUDE essential part */
|
||||
if (oth->syn && !oth->ack && !oth->rst && !oth->fin) {
|
||||
tcph->syn = true;
|
||||
tcph->seq = 0;
|
||||
tcph->ack = true;
|
||||
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
|
||||
oldskb->len - ip_hdrlen(oldskb) -
|
||||
(oth->doff << 2));
|
||||
} else {
|
||||
tcph->rst = true;
|
||||
if (!oth->ack) {
|
||||
tcph->seq = 0;
|
||||
tcph->ack = true;
|
||||
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn +
|
||||
oth->fin + oldskb->len -
|
||||
ip_hdrlen(oldskb) - (oth->doff << 2));
|
||||
} else {
|
||||
tcph->seq = oth->ack_seq;
|
||||
tcph->ack = false;
|
||||
tcph->ack_seq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
|
||||
niph->daddr, csum_partial((char *)tcph,
|
||||
sizeof(struct tcphdr), 0));
|
||||
|
||||
addr_type = RTN_UNSPEC;
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
||||
nskb->nf_bridge->mask & BRNF_BRIDGED))
|
||||
#else
|
||||
if (hook != NF_INET_FORWARD)
|
||||
#endif
|
||||
addr_type = RTN_LOCAL;
|
||||
|
||||
/* ip_route_me_harder expects skb->dst to be set */
|
||||
dst_hold(oldskb->dst);
|
||||
nskb->dst = oldskb->dst;
|
||||
|
||||
if (ip_route_me_harder(nskb, addr_type))
|
||||
goto free_nskb;
|
||||
|
||||
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
||||
nskb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
/* "Never happens" */
|
||||
if (nskb->len > dst_mtu(nskb->dst))
|
||||
goto free_nskb;
|
||||
|
||||
nf_ct_attach(nskb, oldskb);
|
||||
|
||||
ip_local_out(nskb);
|
||||
return;
|
||||
|
||||
free_nskb:
|
||||
kfree_skb(nskb);
|
||||
}
|
||||
|
||||
static unsigned int delude_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
/* WARNING: This code causes reentry within iptables.
|
||||
This means that the iptables jump stack is now crap. We
|
||||
must return an absolute verdict. --RR */
|
||||
delude_send_reset(skb, hooknum);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static struct xt_target delude_tg_reg __read_mostly = {
|
||||
.name = "DELUDE",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.table = "filter",
|
||||
.hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD),
|
||||
.proto = IPPROTO_TCP,
|
||||
.target = delude_tg,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init delude_tg_init(void)
|
||||
{
|
||||
return xt_register_target(&delude_tg_reg);
|
||||
}
|
||||
|
||||
static void __exit delude_tg_exit(void)
|
||||
{
|
||||
xt_unregister_target(&delude_tg_reg);
|
||||
}
|
||||
|
||||
module_init(delude_tg_init);
|
||||
module_exit(delude_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("Xtables: Close TCP connections after handshake");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_DELUDE");
|
263
extensions/xt_portscan.c
Normal file
263
extensions/xt_portscan.c
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* portscan match for netfilter
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_tcpudp.h>
|
||||
#include <net/netfilter/nf_nat_rule.h>
|
||||
#include "xt_portscan.h"
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
enum {
|
||||
TCP_FLAGS_ALL3 = TCP_FLAG_FIN | TCP_FLAG_RST | TCP_FLAG_SYN,
|
||||
TCP_FLAGS_ALL4 = TCP_FLAGS_ALL3 | TCP_FLAG_ACK,
|
||||
TCP_FLAGS_ALL6 = TCP_FLAGS_ALL4 | TCP_FLAG_PSH | TCP_FLAG_URG,
|
||||
};
|
||||
|
||||
/* Module parameters */
|
||||
static unsigned int
|
||||
connmark_mask = ~0,
|
||||
packet_mask = ~0,
|
||||
mark_seen = 0x9,
|
||||
mark_synrcv = 0x1,
|
||||
mark_closed = 0x2,
|
||||
mark_synscan = 0x3,
|
||||
mark_estab1 = 0x4,
|
||||
mark_estab2 = 0x5,
|
||||
mark_cnscan = 0x6,
|
||||
mark_grscan = 0x7,
|
||||
mark_valid = 0x8;
|
||||
|
||||
module_param(connmark_mask, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(packet_mask, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_seen, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_synrcv, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_closed, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_synscan, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_estab1, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_estab2, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_cnscan, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_grscan, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_valid, uint, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(connmark_mask, "only set specified bits in connection mark");
|
||||
MODULE_PARM_DESC(packet_mask, "only set specified bits in packet mark");
|
||||
MODULE_PARM_DESC(mark_seen, "nfmark value for packet-seen state");
|
||||
MODULE_PARM_DESC(mark_synrcv, "connmark value for SYN Received state");
|
||||
MODULE_PARM_DESC(mark_closed, "connmark value for closed state");
|
||||
MODULE_PARM_DESC(mark_synscan, "connmark value for SYN Scan state");
|
||||
MODULE_PARM_DESC(mark_estab1, "connmark value for Established-1 state");
|
||||
MODULE_PARM_DESC(mark_estab2, "connmark value for Established-2 state");
|
||||
MODULE_PARM_DESC(mark_cnscan, "connmark value for Connect Scan state");
|
||||
MODULE_PARM_DESC(mark_grscan, "connmark value for Grab Scan state");
|
||||
MODULE_PARM_DESC(mark_valid, "connmark value for Valid state");
|
||||
|
||||
/* TCP flag functions */
|
||||
static inline bool tflg_ack4(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK;
|
||||
}
|
||||
|
||||
static inline bool tflg_ack6(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK;
|
||||
}
|
||||
|
||||
static inline bool tflg_fin(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN;
|
||||
}
|
||||
|
||||
static inline bool tflg_rst(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST;
|
||||
}
|
||||
|
||||
static inline bool tflg_rstack(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
|
||||
(TCP_FLAG_ACK | TCP_FLAG_RST);
|
||||
}
|
||||
|
||||
static inline bool tflg_syn(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN;
|
||||
}
|
||||
|
||||
static inline bool tflg_synack(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
|
||||
(TCP_FLAG_SYN | TCP_FLAG_ACK);
|
||||
}
|
||||
|
||||
/* portscan functions */
|
||||
static inline bool portscan_mt_stealth(const struct tcphdr *th)
|
||||
{
|
||||
/*
|
||||
* "Connection refused" replies to our own probes must not be matched.
|
||||
*/
|
||||
if (tflg_rstack(th))
|
||||
return false;
|
||||
|
||||
if (tflg_rst(th) && printk_ratelimit()) {
|
||||
printk(KERN_WARNING PFX "Warning: Pure RST received\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* -p tcp ! --syn -m conntrack --ctstate INVALID: Looking for non-start
|
||||
* packets that are not associated with any connection -- this will
|
||||
* match most scan types (NULL, XMAS, FIN) and ridiculous flag
|
||||
* combinations (SYN-RST, SYN-FIN, SYN-FIN-RST, FIN-RST, etc.).
|
||||
*/
|
||||
return !tflg_syn(th);
|
||||
}
|
||||
|
||||
static inline unsigned int portscan_mt_full(int mark,
|
||||
enum ip_conntrack_info ctstate, bool loopback, const struct tcphdr *tcph,
|
||||
unsigned int payload_len)
|
||||
{
|
||||
if (mark == mark_estab2) {
|
||||
/*
|
||||
* -m connmark --mark $ESTAB2
|
||||
*/
|
||||
if (tflg_ack4(tcph) && payload_len == 0)
|
||||
return mark; /* keep mark */
|
||||
else if (tflg_rst(tcph) || tflg_fin(tcph))
|
||||
return mark_grscan;
|
||||
else
|
||||
return mark_valid;
|
||||
} else if (mark == mark_estab1) {
|
||||
/*
|
||||
* -m connmark --mark $ESTAB1
|
||||
*/
|
||||
if (tflg_rst(tcph) || tflg_fin(tcph))
|
||||
return mark_cnscan;
|
||||
else if (!loopback && tflg_ack4(tcph) && payload_len == 0)
|
||||
return mark_estab2;
|
||||
else
|
||||
return mark_valid;
|
||||
} else if (mark == mark_synrcv) {
|
||||
/*
|
||||
* -m connmark --mark $SYN
|
||||
*/
|
||||
if (loopback && tflg_synack(tcph))
|
||||
return mark; /* keep mark */
|
||||
else if (loopback && tflg_rstack(tcph))
|
||||
return mark_closed;
|
||||
else if (tflg_ack6(tcph))
|
||||
return mark_estab1;
|
||||
else
|
||||
return mark_synscan;
|
||||
} else if (ctstate == IP_CT_NEW && tflg_syn(tcph)) {
|
||||
/*
|
||||
* -p tcp --syn --ctstate NEW
|
||||
*/
|
||||
return mark_synrcv;
|
||||
}
|
||||
return mark;
|
||||
}
|
||||
|
||||
static bool portscan_mt(const struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const struct xt_match *match, const void *matchinfo, int offset,
|
||||
unsigned int protoff, bool *hotdrop)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = matchinfo;
|
||||
enum ip_conntrack_info ctstate;
|
||||
const struct tcphdr *tcph;
|
||||
struct nf_conn *ctdata;
|
||||
struct tcphdr tcph_buf;
|
||||
|
||||
tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf);
|
||||
if (tcph == NULL)
|
||||
return false;
|
||||
|
||||
/* Check for invalid packets: -m conntrack --ctstate INVALID */
|
||||
if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) {
|
||||
if (info->match_stealth)
|
||||
return portscan_mt_stealth(tcph);
|
||||
/*
|
||||
* If @ctdata is NULL, we cannot match the other scan
|
||||
* types, return.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If -m portscan was previously applied to this packet, the rules we
|
||||
* simulate must not be run through again. And for speedup, do not call
|
||||
* it either when the connection is already VALID.
|
||||
*/
|
||||
if ((ctdata->mark & connmark_mask) == mark_valid ||
|
||||
(skb->mark & packet_mask) != mark_seen) {
|
||||
unsigned int n;
|
||||
|
||||
n = portscan_mt_full(ctdata->mark & connmark_mask, ctstate,
|
||||
in == init_net__loopback_dev, tcph,
|
||||
skb->len - protoff - 4 * tcph->doff);
|
||||
|
||||
ctdata->mark = (ctdata->mark & ~connmark_mask) | n;
|
||||
((struct sk_buff *)skb)->mark =
|
||||
(skb->mark & ~packet_mask) ^ mark_seen;
|
||||
}
|
||||
|
||||
return (info->match_syn && ctdata->mark == mark_synscan) ||
|
||||
(info->match_cn && ctdata->mark == mark_cnscan) ||
|
||||
(info->match_gr && ctdata->mark == mark_grscan);
|
||||
}
|
||||
|
||||
static bool portscan_mt_check(const char *tablename, const void *entry,
|
||||
const struct xt_match *match, void *matchinfo, unsigned int hook_mask)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = matchinfo;
|
||||
|
||||
if ((info->match_stealth & ~1) || (info->match_syn & ~1) ||
|
||||
(info->match_cn & ~1) || (info->match_gr & ~1)) {
|
||||
printk(KERN_WARNING PFX "Invalid flags\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct xt_match portscan_mt_reg __read_mostly = {
|
||||
.name = "portscan",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.match = portscan_mt,
|
||||
.checkentry = portscan_mt_check,
|
||||
.matchsize = sizeof(struct xt_portscan_mtinfo),
|
||||
.proto = IPPROTO_TCP,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init portscan_mt_init(void)
|
||||
{
|
||||
return xt_register_match(&portscan_mt_reg);
|
||||
}
|
||||
|
||||
static void __exit portscan_mt_exit(void)
|
||||
{
|
||||
xt_unregister_match(&portscan_mt_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(portscan_mt_init);
|
||||
module_exit(portscan_mt_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("netfilter \"portscan\" match");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_portscan");
|
8
extensions/xt_portscan.h
Normal file
8
extensions/xt_portscan.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_PORTSCAN_H
|
||||
#define _LINUX_NETFILTER_XT_PORTSCAN_H 1
|
||||
|
||||
struct xt_portscan_mtinfo {
|
||||
uint8_t match_stealth, match_syn, match_cn, match_gr;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_PORTSCAN_H */
|
Reference in New Issue
Block a user