netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Resend [Patch 2/2] iptables: add random option to SNAT
  2007-01-12 22:53 ` Jan Engelhardt
@ 2007-01-13 12:06   ` Eric Leblond
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Leblond @ 2007-01-13 12:06 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel


[-- 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 --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Resend [patch 2/2] iptables: add random option to SNAT
@ 2007-02-05 13:25 Eric Leblond
  2007-02-05 15:06 ` Patrick McHardy
  0 siblings, 1 reply; 9+ messages in thread
From: Eric Leblond @ 2007-02-05 13:25 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Patrick McHardy, Pablo Neira Ayuso


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

Hi,

This is a resend of :
	http://patchwork.netfilter.org/netfilter-devel/patch.pl?id=36

Merge window for 2.6.21 is open and kernel part of the feature should
reach kernel tree soon...

BR,
-- 
Éric Leblond, eleblond@inl.fr
Téléphone : 01 44 89 46 39, Fax : 01 44 89 45 01
INL, http://www.inl.fr

[-- 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 --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Resend [patch 2/2] iptables: add random option to SNAT
  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
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick McHardy @ 2007-02-05 15:06 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, Pablo Neira Ayuso

Eric Leblond wrote:
> Hi,
> 
> This is a resend of :
> 	http://patchwork.netfilter.org/netfilter-devel/patch.pl?id=36
> 
> Merge window for 2.6.21 is open and kernel part of the feature should
> reach kernel tree soon...


I'm in the process of preparing my patches for upstream submission
(which include your random patch). I'll look into the userspace patch
after that, I'm not a big fan of the :random syntax.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Resend [patch 2/2] iptables: add random option to SNAT
  2007-02-05 15:06 ` Patrick McHardy
@ 2007-02-05 15:55   ` Eric Leblond
  2007-02-12 13:40     ` Patrick McHardy
  0 siblings, 1 reply; 9+ messages in thread
From: Eric Leblond @ 2007-02-05 15:55 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Pablo Neira Ayuso

[-- Attachment #1: Type: text/plain, Size: 686 bytes --]

Hi,

Le lundi 05 février 2007 à 16:06 +0100, Patrick McHardy a écrit :
> Eric Leblond wrote:
> I'm in the process of preparing my patches for upstream submission
> (which include your random patch).

Great.

> I'll look into the userspace patch
> after that, I'm not a big fan of the :random syntax.

I make this choice because iptables had the capabilities to have
multiple NAT ranges and hence randomization has to be linked with the
range.

But we can also assume to have a per iptables rule switch. I can rewrite
my patch in this way if you want.

BR,
-- 
Éric Leblond, eleblond@inl.fr
Téléphone : 01 44 89 46 39, Fax : 01 44 89 45 01
INL, http://www.inl.fr

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Resend [patch 2/2] iptables: add random option to SNAT
  2007-02-05 15:55   ` Eric Leblond
@ 2007-02-12 13:40     ` Patrick McHardy
  2007-02-12 18:38       ` Jan Engelhardt
  2007-02-24 14:10       ` Eric Leblond
  0 siblings, 2 replies; 9+ messages in thread
From: Patrick McHardy @ 2007-02-12 13:40 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, Pablo Neira Ayuso

Eric Leblond wrote:
>>I'll look into the userspace patch
>>after that, I'm not a big fan of the :random syntax.
> 
> 
> I make this choice because iptables had the capabilities to have
> multiple NAT ranges and hence randomization has to be linked with the
> range.

Not anymore since since rustynat changes (~2.6.12).

> 
> But we can also assume to have a per iptables rule switch. I can rewrite
> my patch in this way if you want.

I think I would prefer that.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Resend [patch 2/2] iptables: add random option to SNAT
  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
  1 sibling, 1 reply; 9+ messages in thread
From: Jan Engelhardt @ 2007-02-12 18:38 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Pablo Neira Ayuso, Eric Leblond


On Feb 12 2007 14:40, Patrick McHardy wrote:
>Eric Leblond wrote:
>>>I'll look into the userspace patch
>>>after that, I'm not a big fan of the :random syntax.
>> 
>> 
>> I make this choice because iptables had the capabilities to have
>> multiple NAT ranges and hence randomization has to be linked with the
>> range.
>
>Not anymore since since rustynat changes (~2.6.12).

So what's the proper way to do that then?


Jan
-- 
ft: http://freshmeat.net/p/chaostables/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Resend [patch 2/2] iptables: add random option to SNAT
  2007-02-12 18:38       ` Jan Engelhardt
@ 2007-02-12 19:38         ` Patrick McHardy
  0 siblings, 0 replies; 9+ messages in thread
From: Patrick McHardy @ 2007-02-12 19:38 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel, Pablo Neira Ayuso, Eric Leblond

Jan Engelhardt wrote:
> On Feb 12 2007 14:40, Patrick McHardy wrote:
> 
>>Eric Leblond wrote:
>>
>>>I make this choice because iptables had the capabilities to have
>>>multiple NAT ranges and hence randomization has to be linked with the
>>>range.
>>
>>Not anymore since since rustynat changes (~2.6.12).
> 
> 
> So what's the proper way to do that then?


There is none, nobody was using it.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Resend [patch 2/2] iptables: add random option to SNAT
  2007-02-12 13:40     ` Patrick McHardy
  2007-02-12 18:38       ` Jan Engelhardt
@ 2007-02-24 14:10       ` Eric Leblond
  2007-02-24 14:21         ` Patrick McHardy
  1 sibling, 1 reply; 9+ messages in thread
From: Eric Leblond @ 2007-02-24 14:10 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Pablo Neira Ayuso


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

Hi,

Le lundi 12 février 2007 à 14:40 +0100, Patrick McHardy a écrit :
> > But we can also assume to have a per iptables rule switch. I can rewrite
> > my patch in this way if you want.
> 
> I think I would prefer that.

Here's the corresponding patch. It adds a --random flags to SNAT, SAME
and MASQUERADE targets.

I've also updated man pages by adding this --random option.

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

[-- Attachment #1.2: iptables-randomize-port.diff --]
[-- Type: text/x-patch, Size: 8484 bytes --]

Index: extensions/libipt_MASQUERADE.c
===================================================================
--- extensions/libipt_MASQUERADE.c	(révision 6752)
+++ extensions/libipt_MASQUERADE.c	(copie de travail)
@@ -15,12 +15,21 @@
 	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_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 @@
 			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: extensions/libipt_SNAT.man
===================================================================
--- extensions/libipt_SNAT.man	(révision 6752)
+++ extensions/libipt_SNAT.man	(copie de travail)
@@ -7,7 +7,7 @@
 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 @@
 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
Index: extensions/libipt_SNAT.c
===================================================================
--- extensions/libipt_SNAT.c	(révision 6752)
+++ extensions/libipt_SNAT.c	(copie de travail)
@@ -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 @@
 {
 	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 @@
 
 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 @@
 			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,9 +175,23 @@
 					   "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 @@
 /* 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 @@
 		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: extensions/libipt_SAME.man
===================================================================
--- extensions/libipt_SAME.man	(révision 6752)
+++ extensions/libipt_SAME.man	(copie de travail)
@@ -9,3 +9,7 @@
 .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: extensions/libipt_SAME.c
===================================================================
--- extensions/libipt_SAME.c	(révision 6752)
+++ extensions/libipt_SAME.c	(copie de travail)
@@ -22,13 +22,22 @@
 "				  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 @@
 
 #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 @@
 {
 	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 @@
 				   "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 @@
 		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 @@
 	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 @@
 			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: extensions/libipt_MASQUERADE.man
===================================================================
--- extensions/libipt_MASQUERADE.man	(révision 6752)
+++ extensions/libipt_MASQUERADE.man	(copie de travail)
@@ -14,9 +14,19 @@
 .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).
+
+

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Resend [patch 2/2] iptables: add random option to SNAT
  2007-02-24 14:10       ` Eric Leblond
@ 2007-02-24 14:21         ` Patrick McHardy
  0 siblings, 0 replies; 9+ messages in thread
From: Patrick McHardy @ 2007-02-24 14:21 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, Pablo Neira Ayuso

Eric Leblond wrote:
> Here's the corresponding patch. It adds a --random flags to SNAT, SAME
> and MASQUERADE targets.
> 
> I've also updated man pages by adding this --random option.

Applied, thanks Eric.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2007-02-24 14:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
  -- strict thread matches above, loose matches on Subject: below --
2007-01-12 16:59 [Patch 0/2] Avoid direct connections between NATed hosts Eric Leblond
2007-01-12 22:53 ` Jan Engelhardt
2007-01-13 12:06   ` Resend [Patch 2/2] iptables: add random option to SNAT Eric Leblond

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).