netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Leblond <eric@inl.fr>
To: Jan Engelhardt <jengelh@linux01.gwdg.de>
Cc: netfilter-devel@lists.netfilter.org
Subject: Resend [Patch 2/2] iptables: add random option to SNAT
Date: Sat, 13 Jan 2007 13:06:55 +0100	[thread overview]
Message-ID: <1168690015.9355.2.camel@localhost> (raw)
In-Reply-To: <Pine.LNX.4.61.0701122350230.19224@yvahk01.tjqt.qr>


[-- Attachment #1.1: Type: text/plain, Size: 393 bytes --]

Hi,

Thanks for your remarks.

Le vendredi 12 janvier 2007 à 23:53 +0100, Jan Engelhardt a écrit :
> >This patches against kernel and iptables add the capability to randomize
> >the source port used when doing SNAT.
> 
> You might also want to patch MASQUERADE and SAME.

This new patch adds random support to SNAT, MASQUERADE and SAME.

BR,
-- 
Eric Leblond <eric@inl.fr>
INL

[-- Attachment #1.2: iptables-random-nat.diff --]
[-- Type: text/x-patch, Size: 7534 bytes --]

Index: extensions/libipt_MASQUERADE.c
===================================================================
--- extensions/libipt_MASQUERADE.c	(révision 6735)
+++ extensions/libipt_MASQUERADE.c	(copie de travail)
@@ -14,7 +14,7 @@
 {
 	printf(
 "MASQUERADE v%s options:\n"
-" --to-ports <port>[-<port>]\n"
+" --to-ports [<port>[-<port>]][:random]\n"
 "				Port (range) to map to.\n\n",
 IPTABLES_VERSION);
 }
@@ -40,14 +40,30 @@
 parse_ports(const char *arg, struct ip_nat_multi_range *mr)
 {
 	const char *dash;
+	char *random;
 	int port;
 
+	if (*arg == 'r'){
+		mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+		return;
+	}
+
 	mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 
 	port = atoi(arg);
 	if (port <= 0 || port > 65535)
 		exit_error(PARAMETER_PROBLEM, "Port `%s' not valid\n", arg);
 
+	random = strchr(arg, ':');
+	if (random) {
+		if (*(random+1) == 'r') {
+			mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+			*random = '\0';
+		} else {
+			exit_error(PARAMETER_PROBLEM, "Random specification `%s' not valid\n", arg);
+		}
+	}
+
 	dash = strchr(arg, '-');
 	if (!dash) {
 		mr->range[0].min.tcp.port
@@ -125,8 +141,11 @@
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
+		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+			printf(":random");
 		printf(" ");
-	}
+	} else if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		printf("random ");
 }
 
 /* Saves the union ipt_targinfo in parsable form to stdout. */
@@ -141,8 +160,11 @@
 		printf("--to-ports %hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
+		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+			printf(":random");
 		printf(" ");
-	}
+	} else if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		printf("--to-ports random ");
 }
 
 static struct iptables_target masq = { NULL,
Index: extensions/libipt_SNAT.c
===================================================================
--- extensions/libipt_SNAT.c	(révision 6735)
+++ extensions/libipt_SNAT.c	(copie de travail)
@@ -22,9 +22,11 @@
 {
 	printf(
 "SNAT v%s options:\n"
-" --to-source <ipaddr>[-<ipaddr>][:port-port]\n"
+" --to-source <ipaddr>[-<ipaddr>][:port-port][:random]\n"
 "				Address to map source to.\n"
-"				(You can use this more than once)\n\n",
+"				(You can use this more than once)\n"
+"				random adds randomness in port selection\n"
+"				to avoid attack by port prediction\n",
 IPTABLES_VERSION);
 }
 
@@ -57,7 +59,7 @@
 parse_to(char *arg, int portok, struct ipt_natinfo *info)
 {
 	struct ip_nat_range range;
-	char *colon, *dash, *error;
+	char *colon, *dash, *random;
 	struct in_addr *ip;
 
 	memset(&range, 0, sizeof(range));
@@ -66,44 +68,55 @@
 	if (colon) {
 		int port;
 
-		if (!portok)
-			exit_error(PARAMETER_PROBLEM,
-				   "Need TCP or UDP with port specification");
+		if (*(colon+1) == 'r') {
+			/* syntax is IP1-IP2:R we just set random */
+			range.flags |= IP_NAT_RANGE_PROTO_RANDOM;
+		} else {
+			if (!portok)
+				exit_error(PARAMETER_PROBLEM,
+						"Need TCP or UDP with port specification");
 
-		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+			range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 
-		port = atoi(colon+1);
-		if (port <= 0 || port > 65535)
-			exit_error(PARAMETER_PROBLEM,
-				   "Port `%s' not valid\n", colon+1);
+			port = atoi(colon+1);
+			if (port <= 0 || port > 65535)
+				exit_error(PARAMETER_PROBLEM,
+						"Port `%s' not valid\n", colon+1);
 
-		error = strchr(colon+1, ':');
-		if (error)
-			exit_error(PARAMETER_PROBLEM,
-				   "Invalid port:port syntax - use dash\n");
+			random = strchr(colon+1, ':');
+			if (random) {
+				if (*(random+1) != 'r'){
+				exit_error(PARAMETER_PROBLEM,
+						"Invalid port:port syntax - use dash\n");
+				} else {
+					range.flags |= IP_NAT_RANGE_PROTO_RANDOM;
+					*random = '\0';
+				}
+			}
 
-		dash = strchr(colon, '-');
-		if (!dash) {
-			range.min.tcp.port
-				= range.max.tcp.port
-				= htons(port);
-		} else {
-			int maxport;
+			dash = strchr(colon, '-');
+			if (!dash) {
+				range.min.tcp.port
+					= range.max.tcp.port
+					= htons(port);
+			} else {
+				int maxport;
 
-			maxport = atoi(dash + 1);
-			if (maxport <= 0 || maxport > 65535)
-				exit_error(PARAMETER_PROBLEM,
-					   "Port `%s' not valid\n", dash+1);
-			if (maxport < port)
-				/* People are stupid. */
-				exit_error(PARAMETER_PROBLEM,
-					   "Port range `%s' funky\n", colon+1);
-			range.min.tcp.port = htons(port);
-			range.max.tcp.port = htons(maxport);
+				maxport = atoi(dash + 1);
+				if (maxport <= 0 || maxport > 65535)
+					exit_error(PARAMETER_PROBLEM,
+							"Port `%s' not valid\n", dash+1);
+				if (maxport < port)
+					/* People are stupid. */
+					exit_error(PARAMETER_PROBLEM,
+							"Port range `%s' funky\n", colon+1);
+				range.min.tcp.port = htons(port);
+				range.max.tcp.port = htons(maxport);
+			}
+			/* Starts with a colon? No IP info...*/
+			if (colon == arg)
+				return &(append_range(info, &range)->t);
 		}
-		/* Starts with a colon? No IP info...*/
-		if (colon == arg)
-			return &(append_range(info, &range)->t);
 		*colon = '\0';
 	}
 
@@ -197,6 +210,9 @@
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
 	}
+	if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		printf(":random");
+	}
 }
 
 /* Prints out the targinfo. */
Index: extensions/libipt_SAME.c
===================================================================
--- extensions/libipt_SAME.c	(révision 6735)
+++ extensions/libipt_SAME.c	(copie de travail)
@@ -16,7 +16,7 @@
 {
 	printf(
 "SAME v%s options:\n"
-" --to <ipaddr>-<ipaddr>\n"
+" --to <ipaddr>-<ipaddr>[:random]\n"
 "				Addresses to map source to.\n"
 "				 May be specified more than\n"
 "				  once for multiple ranges.\n"
@@ -49,10 +49,21 @@
 static void
 parse_to(char *arg, struct ip_nat_range *range)
 {
-	char *dash;
+	char *dash, *random;
 	struct in_addr *ip;
 
 	range->flags |= IP_NAT_RANGE_MAP_IPS;
+
+	random = strchr(arg, ':');
+	if (random) {
+		if (*(random+1) == 'r') {
+			range->flags |= IP_NAT_RANGE_PROTO_RANDOM;
+			*random = '\0';
+		} else {
+			exit_error(PARAMETER_PROBLEM, "Random specification `%s' not valid\n", random+1);
+		}
+	}
+
 	dash = strchr(arg, '-');
 
 	if (dash)
@@ -90,7 +101,7 @@
 	struct ipt_same_info *mr
 		= (struct ipt_same_info *)(*target)->data;
 
-	switch (c) {
+switch (c) {
 	case '1':
 		if (mr->rangesize == IPT_SAME_MAX_RANGE)
 			exit_error(PARAMETER_PROBLEM,
@@ -151,10 +162,13 @@
 		printf("%s", addr_to_dotted(&a));
 		a.s_addr = r->max_ip;
 		
-		if (r->min_ip == r->max_ip)
+		if (r->min_ip != r->max_ip)
+			printf("-%s", addr_to_dotted(&a));
+
+		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+			printf(":random ");
+		else
 			printf(" ");
-		else
-			printf("-%s ", addr_to_dotted(&a));
 	}
 	
 	if (mr->info & IPT_SAME_NODST)
@@ -177,10 +191,13 @@
 		printf("--to %s", addr_to_dotted(&a));
 		a.s_addr = r->max_ip;
 
-		if (r->min_ip == r->max_ip)
+		if (r->min_ip != r->max_ip)
+			printf("-%s", addr_to_dotted(&a));
+
+		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+			printf(":random ");
+		else
 			printf(" ");
-		else
-			printf("-%s ", addr_to_dotted(&a));
 	}
 	
 	if (mr->info & IPT_SAME_NODST)

[-- Attachment #2: Ceci est une partie de message numériquement signée --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

  reply	other threads:[~2007-01-13 12:06 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-12 16:59 [Patch 0/2] Avoid direct connections between NATed hosts Eric Leblond
2007-01-12 17:02 ` [Patch 1/2] " Eric Leblond
2007-01-12 17:04 ` [Patch 2/2] iptables: add random option to SNAT Eric Leblond
2007-01-12 17:11 ` [Patch 0/2] Avoid direct connections between NATed hosts Rémi Denis-Courmont
2007-01-12 17:20   ` Patrick McHardy
2007-01-12 17:39     ` Rémi Denis-Courmont
2007-01-17 12:13       ` Patrick McHardy
2007-01-12 22:53 ` Jan Engelhardt
2007-01-13 12:06   ` Eric Leblond [this message]
2007-01-13 21:00   ` Resend [Patch 1/2] " Eric Leblond
2007-01-17 12:23     ` Patrick McHardy
2007-01-17 15:18       ` Eric Leblond
2007-01-19 15:36         ` Patrick McHardy
2007-01-26 14:00         ` Patrick McHardy
  -- strict thread matches above, loose matches on Subject: below --
2007-02-05 13:25 Resend [patch 2/2] iptables: add random option to SNAT Eric Leblond
2007-02-05 15:06 ` Patrick McHardy
2007-02-05 15:55   ` Eric Leblond
2007-02-12 13:40     ` Patrick McHardy
2007-02-12 18:38       ` Jan Engelhardt
2007-02-12 19:38         ` Patrick McHardy
2007-02-24 14:10       ` Eric Leblond
2007-02-24 14:21         ` Patrick McHardy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1168690015.9355.2.camel@localhost \
    --to=eric@inl.fr \
    --cc=jengelh@linux01.gwdg.de \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).