Compare commits

...

8 Commits
v2.14 ... v2.15

Author SHA1 Message Date
Jan Engelhardt
47f5391a37 Xtables-addons 2.15 2021-02-05 19:02:49 +01:00
Jan Engelhardt
16a64492ae xt_lscan: add --mirai option 2021-02-05 19:00:13 +01:00
Jan Engelhardt
cdcf874366 xt_lscan: extend info struct to support more flags (without size change) 2021-01-20 03:09:52 +01:00
Jan Engelhardt
1b4b4347c5 geoip: apply consistent style to xt_geoip_build 2018-02-12 13:58:18 +01:00
Philip Prindeville
2f37af43c5 geoip: selective endianness catalog generation 2018-02-12 13:56:48 +01:00
Jan Engelhardt
56e5970c64 xt_pknock: don't split function heads 2018-01-05 01:36:12 +01:00
Marcelo Henrique Cerri
2b76b68c65 build: support for Linux 4.15
Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
2018-01-05 01:35:12 +01:00
Seth Forshee
d2eeac4c32 build: (additional) support for Linux 4.14
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
2018-01-05 01:35:07 +01:00
10 changed files with 129 additions and 51 deletions

View File

@@ -1,4 +1,4 @@
AC_INIT([xtables-addons], [2.14]) AC_INIT([xtables-addons], [2.15])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View File

@@ -1,6 +1,9 @@
HEAD v2.15 (2021-02-05)
==== ==================
Enhancements:
- support for Linux up to 4.15
- xt_lscan: add --mirai option
v2.14 (2017-11-22) v2.14 (2017-11-22)

View File

@@ -93,4 +93,8 @@ static inline struct net *par_net(const struct xt_action_param *par)
#endif #endif
} }
#ifndef NF_CT_ASSERT
# define NF_CT_ASSERT(x) WARN_ON(!(x))
#endif
#endif /* _XTABLES_COMPAT_H */ #endif /* _XTABLES_COMPAT_H */

View File

@@ -24,6 +24,7 @@ static const struct option lscan_mt_opts[] = {
{.name = "synscan", .has_arg = false, .val = 's'}, {.name = "synscan", .has_arg = false, .val = 's'},
{.name = "cnscan", .has_arg = false, .val = 'c'}, {.name = "cnscan", .has_arg = false, .val = 'c'},
{.name = "grscan", .has_arg = false, .val = 'g'}, {.name = "grscan", .has_arg = false, .val = 'g'},
{.name = "mirai", .has_arg = false, .val = 'm'},
{NULL}, {NULL},
}; };
@@ -35,7 +36,8 @@ static void lscan_mt_help(void)
" --stealth Match TCP Stealth packets\n" " --stealth Match TCP Stealth packets\n"
" --synscan Match TCP SYN scans\n" " --synscan Match TCP SYN scans\n"
" --cnscan Match TCP Connect scans\n" " --cnscan Match TCP Connect scans\n"
" --grscan Match Banner Grabbing scans\n"); " --grscan Match Banner Grabbing scans\n"
" --mirai Match TCP scan with ISN = dest. IP\n");
} }
static int lscan_mt_parse(int c, char **argv, int invert, static int lscan_mt_parse(int c, char **argv, int invert,
@@ -45,16 +47,19 @@ static int lscan_mt_parse(int c, char **argv, int invert,
switch (c) { switch (c) {
case 'c': case 'c':
info->match_cn = true; info->match_fl3 |= LSCAN_FL3_CN;
return true; return true;
case 'g': case 'g':
info->match_gr = true; info->match_fl4 |= LSCAN_FL4_GR;
return true;
case 'm':
info->match_fl1 |= LSCAN_FL1_MIRAI;
return true; return true;
case 's': case 's':
info->match_syn = true; info->match_fl2 |= LSCAN_FL2_SYN;
return true; return true;
case 'x': case 'x':
info->match_stealth = true; info->match_fl1 |= LSCAN_FL1_STEALTH;
return true; return true;
} }
return false; return false;
@@ -68,14 +73,16 @@ static void lscan_mt_save(const void *ip, const struct xt_entry_match *match)
{ {
const struct xt_lscan_mtinfo *info = (const void *)(match->data); const struct xt_lscan_mtinfo *info = (const void *)(match->data);
if (info->match_stealth) if (info->match_fl1 & LSCAN_FL1_STEALTH)
printf(" --stealth "); printf(" --stealth ");
if (info->match_syn) if (info->match_fl2 & LSCAN_FL2_SYN)
printf(" --synscan "); printf(" --synscan ");
if (info->match_cn) if (info->match_fl3 & LSCAN_FL3_CN)
printf(" --cnscan "); printf(" --cnscan ");
if (info->match_gr) if (info->match_fl4 & LSCAN_FL4_GR)
printf(" --grscan "); printf(" --grscan ");
if (info->match_fl1 & LSCAN_FL1_MIRAI)
printf(" --mirai ");
} }
static void lscan_mt_print(const void *ip, static void lscan_mt_print(const void *ip,

View File

@@ -27,6 +27,11 @@ warranted single-direction data flows, usually bulk data transfers such as
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
ports where a protocol runs that is guaranteed to do a bidirectional exchange ports where a protocol runs that is guaranteed to do a bidirectional exchange
of bytes. of bytes.
.TP
\fB\-\-mirai\fP
Match if the TCP ISN is equal to the IPv4 destination address; this is used
by the devices in the Mirai botnet as a form of TCP SYN scan, so you will
have to explicitly specify --syn for the rule.
.PP .PP
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan, NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
so be advised to carefully use xt_lscan in conjunction with blocking rules, so be advised to carefully use xt_lscan in conjunction with blocking rules,

View File

@@ -357,11 +357,18 @@ has_logged_during_this_minute(const struct peer *peer)
* *
* @r: rule * @r: rule
*/ */
static void #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
peer_gc(unsigned long r) static void peer_gc(struct timer_list *tl)
#else
static void peer_gc(unsigned long r)
#endif
{ {
unsigned int i; unsigned int i;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct xt_pknock_rule *rule = from_timer(rule, tl, timer);
#else
struct xt_pknock_rule *rule = (struct xt_pknock_rule *)r; struct xt_pknock_rule *rule = (struct xt_pknock_rule *)r;
#endif
struct peer *peer; struct peer *peer;
struct list_head *pos, *n; struct list_head *pos, *n;
@@ -469,9 +476,13 @@ add_rule(struct xt_pknock_mtinfo *info)
if (rule->peer_head == NULL) if (rule->peer_head == NULL)
goto out; goto out;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&rule->timer, peer_gc, 0);
#else
init_timer(&rule->timer); init_timer(&rule->timer);
rule->timer.function = peer_gc; rule->timer.function = peer_gc;
rule->timer.data = (unsigned long)rule; rule->timer.data = (unsigned long)rule;
#endif
rule->status_proc = proc_create_data(info->rule_name, 0, pde, rule->status_proc = proc_create_data(info->rule_name, 0, pde,
&pknock_proc_ops, rule); &pknock_proc_ops, rule);

View File

@@ -175,6 +175,7 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
{ {
const struct xt_lscan_mtinfo *info = par->matchinfo; const struct xt_lscan_mtinfo *info = par->matchinfo;
enum ip_conntrack_info ctstate; enum ip_conntrack_info ctstate;
const struct iphdr *iph = ip_hdr(skb);
const struct tcphdr *tcph; const struct tcphdr *tcph;
struct nf_conn *ctdata; struct nf_conn *ctdata;
struct tcphdr tcph_buf; struct tcphdr tcph_buf;
@@ -182,10 +183,13 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
tcph = skb_header_pointer(skb, par->thoff, sizeof(tcph_buf), &tcph_buf); tcph = skb_header_pointer(skb, par->thoff, sizeof(tcph_buf), &tcph_buf);
if (tcph == NULL) if (tcph == NULL)
return false; return false;
if (info->match_fl1 & LSCAN_FL1_MIRAI && iph != NULL &&
iph->version == 4 && iph->daddr == tcph->seq)
return true;
/* Check for invalid packets: -m conntrack --ctstate INVALID */ /* Check for invalid packets: -m conntrack --ctstate INVALID */
if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) {
if (info->match_stealth) if (info->match_fl1 & LSCAN_FL1_STEALTH)
return lscan_mt_stealth(tcph); return lscan_mt_stealth(tcph);
/* /*
* If @ctdata is NULL, we cannot match the other scan * If @ctdata is NULL, we cannot match the other scan
@@ -215,17 +219,19 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen; skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen;
} }
return (info->match_syn && ctdata->mark == mark_synscan) || return (info->match_fl1 & LSCAN_FL1_STEALTH && ctdata->mark == mark_synscan) ||
(info->match_cn && ctdata->mark == mark_cnscan) || (info->match_fl3 & LSCAN_FL3_CN && ctdata->mark == mark_cnscan) ||
(info->match_gr && ctdata->mark == mark_grscan); (info->match_fl4 & LSCAN_FL4_GR && ctdata->mark == mark_grscan);
} }
static int lscan_mt_check(const struct xt_mtchk_param *par) static int lscan_mt_check(const struct xt_mtchk_param *par)
{ {
const struct xt_lscan_mtinfo *info = par->matchinfo; const struct xt_lscan_mtinfo *info = par->matchinfo;
if ((info->match_stealth & ~1) || (info->match_syn & ~1) || if ((info->match_fl1 & ~(LSCAN_FL1_STEALTH | LSCAN_FL1_MIRAI)) ||
(info->match_cn & ~1) || (info->match_gr & ~1)) { (info->match_fl2 & ~LSCAN_FL2_SYN) ||
(info->match_fl3 & ~LSCAN_FL3_CN) ||
(info->match_fl4 & ~LSCAN_FL4_GR)) {
printk(KERN_WARNING PFX "Invalid flags\n"); printk(KERN_WARNING PFX "Invalid flags\n");
return -EINVAL; return -EINVAL;
} }

View File

@@ -1,8 +1,16 @@
#ifndef _LINUX_NETFILTER_XT_LSCAN_H #ifndef _LINUX_NETFILTER_XT_LSCAN_H
#define _LINUX_NETFILTER_XT_LSCAN_H 1 #define _LINUX_NETFILTER_XT_LSCAN_H 1
enum {
LSCAN_FL1_STEALTH = 1 << 0,
LSCAN_FL1_MIRAI = 1 << 1,
LSCAN_FL2_SYN = 1 << 0,
LSCAN_FL3_CN = 1 << 0,
LSCAN_FL4_GR = 1 << 0,
};
struct xt_lscan_mtinfo { struct xt_lscan_mtinfo {
uint8_t match_stealth, match_syn, match_cn, match_gr; uint8_t match_fl1, match_fl2, match_fl3, match_fl4;
}; };
#endif /* _LINUX_NETFILTER_XT_LSCAN_H */ #endif /* _LINUX_NETFILTER_XT_LSCAN_H */

View File

@@ -8,23 +8,45 @@ use IO::Handle;
use Text::CSV_XS; # or trade for Text::CSV use Text::CSV_XS; # or trade for Text::CSV
use strict; use strict;
my $le32 = pack("V", 0x10000000);
my $be32 = pack("N", 0x10000000);
my $u32 = undef;
sub wantBE { return !$u32 || $u32 eq $be32; }
sub wantLE { return !$u32 || $u32 eq $le32; }
my $csv = Text::CSV_XS->new({ my $csv = Text::CSV_XS->new({
allow_whitespace => 1, allow_whitespace => 1,
binary => 1, binary => 1,
eol => $/, eol => $/,
}); # or Text::CSV }); # or Text::CSV
my $target_dir = "."; my $target_dir = ".";
my $native_only = 0;
&Getopt::Long::Configure(qw(bundling)); &Getopt::Long::Configure(qw(bundling));
&GetOptions( &GetOptions(
"D=s" => \$target_dir, "D=s" => \$target_dir,
"n" => \$native_only,
); );
if (!-d $target_dir) { if (!-d $target_dir) {
print STDERR "Target directory $target_dir does not exist.\n"; print STDERR "Target directory $target_dir does not exist.\n";
exit 1; exit 1;
} }
foreach (qw(LE BE)) { my @dbs = qw(LE BE);
if ($native_only) {
$u32 = pack("L", 0x10000000);
if ($u32 eq $le32) {
@dbs = qw(LE);
} elsif ($u32 eq $be32) {
@dbs = qw(BE);
} else {
print STDERRR "Cannot determine endianness.\n";
exit 1;
}
}
foreach (@dbs) {
my $dir = "$target_dir/$_"; my $dir = "$target_dir/$_";
if (!-e $dir && !mkdir($dir)) { if (!-e $dir && !mkdir($dir)) {
print STDERR "Could not mkdir $dir: $!\n"; print STDERR "Could not mkdir $dir: $!\n";
@@ -80,11 +102,18 @@ sub dump_one
scalar(@{$country->{pool_v6}}), scalar(@{$country->{pool_v6}}),
$iso_code, $country->{name}; $iso_code, $country->{name};
if (wantLE) {
$file = "$target_dir/LE/".uc($iso_code).".iv6"; $file = "$target_dir/LE/".uc($iso_code).".iv6";
if (!open($fh_le, "> $file")) { if (!open($fh_le, "> $file")) {
print STDERR "Error opening $file: $!\n"; print STDERR "Error opening $file: $!\n";
exit 1; exit 1;
} }
foreach my $range (@{$country->{pool_v6}}) {
print $fh_le &ip6_swap($range->[0]), &ip6_swap($range->[1]);
}
close $fh_le;
}
if (wantBE) {
$file = "$target_dir/BE/".uc($iso_code).".iv6"; $file = "$target_dir/BE/".uc($iso_code).".iv6";
if (!open($fh_be, "> $file")) { if (!open($fh_be, "> $file")) {
print STDERR "Error opening $file: $!\n"; print STDERR "Error opening $file: $!\n";
@@ -92,32 +121,37 @@ sub dump_one
} }
foreach my $range (@{$country->{pool_v6}}) { foreach my $range (@{$country->{pool_v6}}) {
print $fh_be $range->[0], $range->[1]; print $fh_be $range->[0], $range->[1];
print $fh_le &ip6_swap($range->[0]), &ip6_swap($range->[1]);
} }
close $fh_le;
close $fh_be; close $fh_be;
}
printf "%5u IPv4 ranges for %s %s\n", printf "%5u IPv4 ranges for %s %s\n",
scalar(@{$country->{pool_v4}}), scalar(@{$country->{pool_v4}}),
$iso_code, $country->{name}; $iso_code, $country->{name};
if (wantLE) {
$file = "$target_dir/LE/".uc($iso_code).".iv4"; $file = "$target_dir/LE/".uc($iso_code).".iv4";
if (!open($fh_le, "> $file")) { if (!open($fh_le, "> $file")) {
print STDERR "Error opening $file: $!\n"; print STDERR "Error opening $file: $!\n";
exit 1; exit 1;
} }
foreach my $range (@{$country->{pool_v4}}) {
print $fh_le pack("VV", $range->[0], $range->[1]);
}
close $fh_le;
}
if (wantBE) {
$file = "$target_dir/BE/".uc($iso_code).".iv4"; $file = "$target_dir/BE/".uc($iso_code).".iv4";
if (!open($fh_be, "> $file")) { if (!open($fh_be, "> $file")) {
print STDERR "Error opening $file: $!\n"; print STDERR "Error opening $file: $!\n";
exit 1; exit 1;
} }
foreach my $range (@{$country->{pool_v4}}) { foreach my $range (@{$country->{pool_v4}}) {
print $fh_le pack("VV", $range->[0], $range->[1]);
print $fh_be pack("NN", $range->[0], $range->[1]); print $fh_be pack("NN", $range->[0], $range->[1]);
} }
close $fh_le;
close $fh_be; close $fh_be;
} }
}
sub ip6_pack sub ip6_pack
{ {

View File

@@ -1,4 +1,4 @@
.TH xtables-addons 8 "" "" "v2.14 (2017-11-22)" .TH xtables-addons 8 "" "" "v2.15 (2021-02-05)"
.SH Name .SH Name
Xtables-addons \(em additional extensions for iptables, ip6tables, etc. Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets .SH Targets