summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Leblond <eric@inl.fr>2007-02-24 15:11:33 +0000
committerPatrick McHardy <kaber@trash.net>2007-02-24 15:11:33 +0000
commitae4b0b3aa70c67f2eff303a3e75834e45c3794a7 (patch)
tree206f258318c77aefd215255edfc680f39311dc6d
parentee9e2205dfd53ffc35495dd60b43c59b77aa3839 (diff)
iptables: add random option to SNAT (Eric Leblond)
-rw-r--r--extensions/libipt_MASQUERADE.c23
-rw-r--r--extensions/libipt_MASQUERADE.man10
-rw-r--r--extensions/libipt_SAME.c43
-rw-r--r--extensions/libipt_SAME.man4
-rw-r--r--extensions/libipt_SNAT.c39
-rw-r--r--extensions/libipt_SNAT.man7
6 files changed, 117 insertions, 9 deletions
diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c
index 7eddcc09..e06333ab 100644
--- a/extensions/libipt_MASQUERADE.c
+++ b/extensions/libipt_MASQUERADE.c
@@ -15,12 +15,21 @@ help(void)
printf(
"MASQUERADE v%s options:\n"
" --to-ports <port>[-<port>]\n"
-" Port (range) to map to.\n\n",
+" Port (range) to map to.\n"
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+" --random\n"
+" Randomize source port.\n"
+#endif
+"\n"
+,
IPTABLES_VERSION);
}
static struct option opts[] = {
{ "to-ports", 1, 0, '1' },
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ { "random", 0, 0, '2' },
+#endif
{ 0 }
};
@@ -100,6 +109,12 @@ parse(int c, char **argv, int invert, unsigned int *flags,
parse_ports(optarg, mr);
return 1;
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ case '2':
+ mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+ return 1;
+#endif
+
default:
return 0;
}
@@ -127,6 +142,12 @@ print(const struct ipt_ip *ip,
printf("-%hu", ntohs(r->max.tcp.port));
printf(" ");
}
+
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+ printf("random");
+ }
+#endif
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
diff --git a/extensions/libipt_MASQUERADE.man b/extensions/libipt_MASQUERADE.man
index e82063cc..01dea51c 100644
--- a/extensions/libipt_MASQUERADE.man
+++ b/extensions/libipt_MASQUERADE.man
@@ -14,9 +14,19 @@ any established connections are lost anyway). It takes one option:
.TP
.BR "--to-ports " "\fIport\fP[-\fIport\fP]"
This specifies a range of source ports to use, overriding the default
+.TP
+.BR "--random"
+Randomize source port mapping
+.TP
.B SNAT
source port-selection heuristics (see above). This is only valid
if the rule also specifies
.B "-p tcp"
or
.BR "-p udp" .
+If option
+.B "--random"
+is used then port mapping will be forcely randomized to avoid
+attacks based on port prediction (kernel >= 2.6.21).
+
+
diff --git a/extensions/libipt_SAME.c b/extensions/libipt_SAME.c
index 4eda2237..625a78a7 100644
--- a/extensions/libipt_SAME.c
+++ b/extensions/libipt_SAME.c
@@ -22,13 +22,22 @@ help(void)
" once for multiple ranges.\n"
" --nodst\n"
" Don't use destination-ip in\n"
-" source selection\n",
+" source selection\n"
+
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+" --random\n"
+" Randomize source port\n"
+#endif
+,
IPTABLES_VERSION);
}
static struct option opts[] = {
{ "to", 1, 0, '1' },
{ "nodst", 0, 0, '2'},
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ { "random", 0, 0, '3' },
+#endif
{ 0 }
};
@@ -79,6 +88,9 @@ parse_to(char *arg, struct ip_nat_range *range)
#define IPT_SAME_OPT_TO 0x01
#define IPT_SAME_OPT_NODST 0x02
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+# define IPT_SAME_OPT_RANDOM 0x04
+#endif
/* Function which parses command options; returns true if it
ate an option */
@@ -89,6 +101,9 @@ parse(int c, char **argv, int invert, unsigned int *flags,
{
struct ipt_same_info *mr
= (struct ipt_same_info *)(*target)->data;
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ int count;
+#endif
switch (c) {
case '1':
@@ -102,6 +117,11 @@ parse(int c, char **argv, int invert, unsigned int *flags,
"Unexpected `!' after --to");
parse_to(optarg, &mr->range[mr->rangesize]);
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ if (*flags & IPT_SAME_OPT_RANDOM)
+ mr->range[mr->rangesize].flags
+ |= IP_NAT_RANGE_PROTO_RANDOM;
+#endif
mr->rangesize++;
*flags |= IPT_SAME_OPT_TO;
break;
@@ -114,7 +134,14 @@ parse(int c, char **argv, int invert, unsigned int *flags,
mr->info |= IPT_SAME_NODST;
*flags |= IPT_SAME_OPT_NODST;
break;
-
+
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ case '3':
+ *flags |= IPT_SAME_OPT_RANDOM;
+ for (count=0; count < mr->rangesize; count++)
+ mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+ break;
+#endif
default:
return 0;
}
@@ -139,6 +166,9 @@ print(const struct ipt_ip *ip,
int count;
struct ipt_same_info *mr
= (struct ipt_same_info *)target->data;
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ int random = 0;
+#endif
printf("same:");
@@ -155,10 +185,19 @@ print(const struct ipt_ip *ip,
printf(" ");
else
printf("-%s ", addr_to_dotted(&a));
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+ random = 1;
+#endif
}
if (mr->info & IPT_SAME_NODST)
printf("nodst ");
+
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ if (random)
+ printf("random ");
+#endif
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
diff --git a/extensions/libipt_SAME.man b/extensions/libipt_SAME.man
index 817c2001..4e88d48d 100644
--- a/extensions/libipt_SAME.man
+++ b/extensions/libipt_SAME.man
@@ -9,3 +9,7 @@ multiple ranges.
.B "--nodst"
Don't use the destination-ip in the calculations when selecting the
new source-ip
+.TP
+.B "--random"
+Port mapping will be forcely randomized to avoid attacks based on
+port prediction (kernel >= 2.6.21).
diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c
index 867c9d01..36147397 100644
--- a/extensions/libipt_SNAT.c
+++ b/extensions/libipt_SNAT.c
@@ -8,6 +8,11 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#define IPT_SNAT_OPT_SOURCE 0x01
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+# define IPT_SNAT_OPT_RANDOM 0x02
+#endif
+
/* Source NAT data consists of a multi-range, indicating where to map
to. */
struct ipt_natinfo
@@ -22,7 +27,11 @@ help(void)
{
printf(
"SNAT v%s options:\n"
-" --to-source <ipaddr>[-<ipaddr>][:port-port]\n"
+" --to-source <ipaddr>[-<ipaddr>][:port-port]"
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+"[--random]"
+#endif
+"\n"
" Address to map source to.\n"
" (You can use this more than once)\n\n",
IPTABLES_VERSION);
@@ -30,6 +39,9 @@ IPTABLES_VERSION);
static struct option opts[] = {
{ "to-source", 1, 0, '1' },
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ { "random", 0, 0, '2' },
+#endif
{ 0 }
};
@@ -155,7 +167,7 @@ parse(int c, char **argv, int invert, unsigned int *flags,
exit_error(PARAMETER_PROBLEM,
"Unexpected `!' after --to-source");
- if (*flags) {
+ if (*flags & IPT_SNAT_OPT_SOURCE) {
if (!kernel_version)
get_kernel_version();
if (kernel_version > LINUX_VERSION(2, 6, 10))
@@ -163,8 +175,22 @@ parse(int c, char **argv, int invert, unsigned int *flags,
"Multiple --to-source not supported");
}
*target = parse_to(optarg, portok, info);
- *flags = 1;
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ if (*flags & IPT_SNAT_OPT_RANDOM)
+ info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+#endif
+ *flags = IPT_SNAT_OPT_SOURCE;
+ return 1;
+
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ case '2':
+ if (*flags & IPT_SNAT_OPT_SOURCE) {
+ info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+ *flags |= IPT_SNAT_OPT_RANDOM;
+ } else
+ *flags |= IPT_SNAT_OPT_RANDOM;
return 1;
+#endif
default:
return 0;
@@ -174,7 +200,7 @@ parse(int c, char **argv, int invert, unsigned int *flags,
/* Final check; must have specfied --to-source. */
static void final_check(unsigned int flags)
{
- if (!flags)
+ if (!(flags & IPT_SNAT_OPT_SOURCE))
exit_error(PARAMETER_PROBLEM,
"You must specify --to-source");
}
@@ -197,6 +223,11 @@ static void print_range(const struct ip_nat_range *r)
if (r->max.tcp.port != r->min.tcp.port)
printf("-%hu", ntohs(r->max.tcp.port));
}
+#ifdef IP_NAT_RANGE_PROTO_RANDOM
+ if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+ printf(" random");
+ }
+#endif
}
/* Prints out the targinfo. */
diff --git a/extensions/libipt_SNAT.man b/extensions/libipt_SNAT.man
index 2d9427f1..daef78f1 100644
--- a/extensions/libipt_SNAT.man
+++ b/extensions/libipt_SNAT.man
@@ -7,7 +7,7 @@ modified (and all future packets in this connection will also be
mangled), and rules should cease being examined. It takes one type
of option:
.TP
-.BR "--to-source " "\fIipaddr\fP[-\fIipaddr\fP][:\fIport\fP-\fIport\fP]"
+.BR "--to-source " "\fIipaddr\fP[-\fIipaddr\fP][:\fIport\fP-\fIport\fP]" [ "--random" ]
which can specify a single new source IP address, an inclusive range
of IP addresses, and optionally, a port range (which is only valid if
the rule also specifies
@@ -17,7 +17,10 @@ or
If no port range is specified, then source ports below 512 will be
mapped to other ports below 512: those between 512 and 1023 inclusive
will be mapped to ports below 1024, and other ports will be mapped to
-1024 or above. Where possible, no port alteration will occur.
+1024 or above. Where possible, no port alteration will If option
+.B "--random"
+is used then port mapping will be forcely randomized to avoid
+attacks based on port prediction (kernel >= 2.6.21).
.RS
.PP
In Kernels up to 2.6.10, you can add several --to-source options. For those