]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
iptables: add random option to SNAT (Eric Leblond)
authorEric Leblond <eric@inl.fr>
Sat, 24 Feb 2007 15:11:33 +0000 (15:11 +0000)
committerPatrick McHardy <kaber@trash.net>
Sat, 24 Feb 2007 15:11:33 +0000 (15:11 +0000)
extensions/libipt_MASQUERADE.c
extensions/libipt_MASQUERADE.man
extensions/libipt_SAME.c
extensions/libipt_SAME.man
extensions/libipt_SNAT.c
extensions/libipt_SNAT.man

index 7eddcc09bbd317a9c551b245636a8a0217378a4f..e06333abae821cc5c69d7e3c69184bee0b45b591 100644 (file)
@@ -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. */
index e82063cc12cb9f4db8ba806deff31dcf48a602ba..01dea51c4cafb66ea2166462486268f6454e8358 100644 (file)
@@ -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).
+
+
index 4eda2237723768b3ab617e5fe3baa385e1d0edf2..625a78a74f06b15775baf285b43c181f2129a739 100644 (file)
@@ -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. */
index 817c20010993ae9fd36ac88feafa32f052c554f4..4e88d48d015f33ae33482592d0ef7844caf8312c 100644 (file)
@@ -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).
index 867c9d010336fe59a3156dd7e80c9d3eeb442357..36147397a71b16ff1260108421839f27abee58fb 100644 (file)
@@ -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. */
index 2d9427f1c57fb7f48aa5b37940ef947b5e22ecfb..daef78f18220aed21e32bc9aa89752d0a6d1795b 100644 (file)
@@ -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