All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch 0/2] Avoid direct connections between NATed hosts
@ 2007-01-12 16:59 Eric Leblond
  2007-01-12 17:02 ` [Patch 1/2] " Eric Leblond
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Eric Leblond @ 2007-01-12 16:59 UTC (permalink / raw)
  To: netfilter-devel

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

Hi,

Some algorithms can be used to established direct connections between
NATed hosts. Skype is one of the programs using this kind of "feature".

Some details can be found here :
	http://www.heise-security.co.uk/articles/print/82481

It uses the fact that port is usually sequentially increased and is thus
predictable.

This patches against kernel and iptables add the capability to randomize
the source port used when doing SNAT.

Tests have been done and have show that Skype is no more able to
established a direct connection between NATed hosts.

Randomization of the source port can be activated on a per-rule basis
with the following syntax:

iptables -A POSTROUTING -t nat -o eth0 -j SNAT --to 192.168.1.3:random

or

iptables -A POSTROUTING -t nat -o eth0 -j SNAT --to 192.168.1.3:1234-3456:random

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] 14+ messages in thread

* [Patch 1/2] Avoid direct connections between NATed hosts
  2007-01-12 16:59 [Patch 0/2] Avoid direct connections between NATed hosts Eric Leblond
@ 2007-01-12 17:02 ` Eric Leblond
  2007-01-12 17:04 ` [Patch 2/2] iptables: add random option to SNAT Eric Leblond
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Eric Leblond @ 2007-01-12 17:02 UTC (permalink / raw)
  To: netfilter-devel


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

Hi,

Here's the patch against Linux git tree (2.6.20-rc4).

It modifies nf_nat and ip_nat.

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: 0002-Add-flags-on-SNAT-rules-to-add-randomness-in-protocol.txt --]
[-- Type: text/plain, Size: 7029 bytes --]

Signed-off-by: Eric Leblond <eric@inl.fr>
---
 include/linux/netfilter_ipv4/ip_nat.h |    1 +
 include/net/netfilter/nf_nat.h        |    1 +
 net/ipv4/netfilter/ip_nat_core.c      |   13 +++++++++++--
 net/ipv4/netfilter/ip_nat_proto_tcp.c |    6 ++++++
 net/ipv4/netfilter/ip_nat_proto_udp.c |    6 ++++++
 net/ipv4/netfilter/nf_nat_core.c      |   13 +++++++++++--
 net/ipv4/netfilter/nf_nat_proto_tcp.c |    5 +++++
 net/ipv4/netfilter/nf_nat_proto_udp.c |    3 +++
 8 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
index bdf5536..bbca89a 100644
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !

 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
+#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */

 /* NAT sequence number modifications */
 struct ip_nat_seq {
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index 61c6206..bc57dd7 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !

 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
+#define IP_NAT_RANGE_PROTO_RANDOM 4

 /* NAT sequence number modifications */
 struct nf_nat_seq {
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9d1a517..fb0a73e 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -246,8 +246,10 @@ get_unique_tuple(struct ip_conntrack_tup
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		if (find_appropriate_src(orig_tuple, tuple, range)) {
 			DEBUGP("get_unique_tuple: Found current src map\n");
-			if (!ip_nat_used_tuple(tuple, conntrack))
-				return;
+			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
+				if (!ip_nat_used_tuple(tuple, conntrack))
+					return;
+			}
 		}
 	}

@@ -261,6 +263,13 @@ get_unique_tuple(struct ip_conntrack_tup

 	proto = ip_nat_proto_find_get(orig_tuple->dst.protonum);

+	/* Change protocol info to have some randomization */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		proto->unique_tuple(tuple, range, maniptype, conntrack);
+		ip_nat_proto_put(proto);
+		return;
+	}
+
 	/* Only bother mapping if it's not already in range and unique */
 	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
 	     || proto->in_range(tuple, maniptype, &range->min, &range->max))
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index b586d18..6869ad7 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -18,6 +18,8 @@ #include <linux/netfilter_ipv4/ip_nat_ru
 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
 #include <linux/netfilter_ipv4/ip_nat_core.h>

+#include <linux/random.h>
+
 static int
 tcp_in_range(const struct ip_conntrack_tuple *tuple,
 	     enum ip_nat_manip_type maniptype,
@@ -75,6 +77,10 @@ tcp_unique_tuple(struct ip_conntrack_tup
 		range_size = ntohs(range->max.tcp.port) - min + 1;
 	}

+	/* Start from random port to avoid prediction */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		get_random_bytes(&port,sizeof(port));
+	}
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!ip_nat_used_tuple(tuple, conntrack)) {
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 5ced087..38d0def 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -18,6 +18,8 @@ #include <linux/netfilter_ipv4/ip_nat_co
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_nat_protocol.h>

+#include <linux/random.h>
+
 static int
 udp_in_range(const struct ip_conntrack_tuple *tuple,
 	     enum ip_nat_manip_type maniptype,
@@ -74,6 +76,10 @@ udp_unique_tuple(struct ip_conntrack_tup
 		range_size = ntohs(range->max.udp.port) - min + 1;
 	}

+	/* Start from random port to avoid prediction */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		get_random_bytes(&port,sizeof(port));
+	}
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!ip_nat_used_tuple(tuple, conntrack))
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 86a9227..9f1b4ec 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -254,8 +254,10 @@ get_unique_tuple(struct nf_conntrack_tup
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		if (find_appropriate_src(orig_tuple, tuple, range)) {
 			DEBUGP("get_unique_tuple: Found current src map\n");
-			if (!nf_nat_used_tuple(tuple, ct))
-				return;
+			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
+				if (!nf_nat_used_tuple(tuple, ct))
+					return;
+			}
 		}
 	}

@@ -269,6 +271,13 @@ get_unique_tuple(struct nf_conntrack_tup

 	proto = nf_nat_proto_find_get(orig_tuple->dst.protonum);

+	/* Change protocol info to have some randomization */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		proto->unique_tuple(tuple, range, maniptype, ct);
+		nf_nat_proto_put(proto);
+		return;
+	}
+
 	/* Only bother mapping if it's not already in range and unique */
 	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
 	     proto->in_range(tuple, maniptype, &range->min, &range->max)) &&
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index 7e26a7e..c348bc9 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -18,6 +18,8 @@ #include <net/netfilter/nf_nat_rule.h>
 #include <net/netfilter/nf_nat_protocol.h>
 #include <net/netfilter/nf_nat_core.h>

+#include <linux/random.h>
+
 static int
 tcp_in_range(const struct nf_conntrack_tuple *tuple,
 	     enum nf_nat_manip_type maniptype,
@@ -75,6 +77,9 @@ tcp_unique_tuple(struct nf_conntrack_tup
 		range_size = ntohs(range->max.tcp.port) - min + 1;
 	}

+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		get_random_bytes(&port,sizeof(port));
+	}
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!nf_nat_used_tuple(tuple, ct))
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
index ab0ce4c..9700f05 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -73,6 +73,9 @@ udp_unique_tuple(struct nf_conntrack_tup
 		range_size = ntohs(range->max.udp.port) - min + 1;
 	}

+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		get_random_bytes(&port,sizeof(port));
+	}
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!nf_nat_used_tuple(tuple, ct))
--
1.4.1


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

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

* [Patch 2/2] iptables: add random option to SNAT
  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 ` Eric Leblond
  2007-01-12 17:11 ` [Patch 0/2] Avoid direct connections between NATed hosts Rémi Denis-Courmont
  2007-01-12 22:53 ` Jan Engelhardt
  3 siblings, 0 replies; 14+ messages in thread
From: Eric Leblond @ 2007-01-12 17:04 UTC (permalink / raw)
  To: netfilter-devel


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

Hi,

Here's the patch against iptables.

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: 3626 bytes --]

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. */

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

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

* Re: [Patch 0/2] Avoid direct connections between NATed hosts
  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 ` Rémi Denis-Courmont
  2007-01-12 17:20   ` Patrick McHardy
  2007-01-12 22:53 ` Jan Engelhardt
  3 siblings, 1 reply; 14+ messages in thread
From: Rémi Denis-Courmont @ 2007-01-12 17:11 UTC (permalink / raw)
  To: netfilter-devel

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

Le vendredi 12 janvier 2007 18:59, Eric Leblond a écrit :
> Some algorithms can be used to established direct connections between
> NATed hosts. Skype is one of the programs using this kind of
> "feature".

NAT are not *security* devices; NATs are meant to *improve* IP usability 
by allowing as many protocols as possible to operate even though there 
are not enough public IP addresses. Making it more difficult for P2P 
apps to operate through is hence completely not only non-sensical, but 
a plain contradiction.

NATs are sufficiently broken and annoying already to handle for software 
development; please do not make them worst. Also, this patch goes 
completely against work-in-progress NAT standards.

In this particular case, your approach is a completely associal 
short-term solution. In the long run, it will simply cause people with 
normal/correct NATs to have to relay even more traffic when they should 
not have to, because of people like you. And it certainly won't prevent 
Skype from running on your network either.

-- 
Rémi Denis-Courmont
http://www.remlab.net/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [Patch 0/2] Avoid direct connections between NATed hosts
  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
  0 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-01-12 17:20 UTC (permalink / raw)
  To: Rémi Denis-Courmont; +Cc: netfilter-devel

Rémi Denis-Courmont wrote:
> Le vendredi 12 janvier 2007 18:59, Eric Leblond a écrit :
> 
>>Some algorithms can be used to established direct connections between
>>NATed hosts. Skype is one of the programs using this kind of
>>"feature".
> 
> 
> NAT are not *security* devices; NATs are meant to *improve* IP usability 
> by allowing as many protocols as possible to operate even though there 
> are not enough public IP addresses. Making it more difficult for P2P 
> apps to operate through is hence completely not only non-sensical, but 
> a plain contradiction.
> 
> NATs are sufficiently broken and annoying already to handle for software 
> development; please do not make them worst. Also, this patch goes 
> completely against work-in-progress NAT standards.

Fully agreed.

> In this particular case, your approach is a completely associal 
> short-term solution. In the long run, it will simply cause people with 
> normal/correct NATs to have to relay even more traffic when they should 
> not have to, because of people like you. And it certainly won't prevent 
> Skype from running on your network either.

Port randomization would still be a useful feature, not to wilfully
break skype, but to make spoofing attacks harder. Currently we
undo randomization done by the operating system/application. Since
its optional I don't see real harm in it.

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

* Re: [Patch 0/2] Avoid direct connections between NATed hosts
  2007-01-12 17:20   ` Patrick McHardy
@ 2007-01-12 17:39     ` Rémi Denis-Courmont
  2007-01-17 12:13       ` Patrick McHardy
  0 siblings, 1 reply; 14+ messages in thread
From: Rémi Denis-Courmont @ 2007-01-12 17:39 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel

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

Le vendredi 12 janvier 2007 19:20, Patrick McHardy a écrit :
> > In this particular case, your approach is a completely associal
> > short-term solution. In the long run, it will simply cause people
> > with normal/correct NATs to have to relay even more traffic when
> > they should not have to, because of people like you. And it
> > certainly won't prevent Skype from running on your network either.
>
> Port randomization would still be a useful feature, not to wilfully
> break skype, but to make spoofing attacks harder. Currently we
> undo randomization done by the operating system/application. Since
> its optional I don't see real harm in it.

Right, randomizing port numbers when they are allocated can make it 
slightly more difficult to spoof DNS. Does the "regular" socket code 
picks port at random or not though? And is the port allocation logic 
shared between socket and NAT code (IMHO it should either be shared or 
at least be equivalent)? It makes little sense to secure host behind 
the NAT and not secure yourself; that also imples there should be no 
need for an iptables option to enable/disable it.

My concern is with when (and how) Netfilter NAT code allocates a new 
port number. If the source private-IP/port are identical, the external 
NATed-IP/port ought be identical too, and certainly not another 
randomized value.

With that, you have the advantage of random source port numbers (better 
spoof protection), while not breaking any NAT-aware P2P app.

Sorry for the misunderstanding.

-- 
Rémi Denis-Courmont
http://www.remlab.net/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [Patch 0/2] Avoid direct connections between NATed hosts
  2007-01-12 16:59 [Patch 0/2] Avoid direct connections between NATed hosts Eric Leblond
                   ` (2 preceding siblings ...)
  2007-01-12 17:11 ` [Patch 0/2] Avoid direct connections between NATed hosts Rémi Denis-Courmont
@ 2007-01-12 22:53 ` Jan Engelhardt
  2007-01-13 12:06   ` Resend [Patch 2/2] iptables: add random option to SNAT Eric Leblond
  2007-01-13 21:00   ` Resend [Patch 1/2] Avoid direct connections between NATed hosts Eric Leblond
  3 siblings, 2 replies; 14+ messages in thread
From: Jan Engelhardt @ 2007-01-12 22:53 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel


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


>+			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
>+				if (!ip_nat_used_tuple(tuple, conntrack))
>+					return;
>+			}
> 		}
> 	}
>

Drop the extra { } - various places.

>@@ -18,6 +18,8 @@ #include <linux/netfilter_ipv4/ip_nat_co
> #include <linux/netfilter_ipv4/ip_nat_rule.h>
> #include <linux/netfilter_ipv4/ip_nat_protocol.h>
>
>+#include <linux/random.h>
>+
> static int
> udp_in_range(const struct ip_conntrack_tuple *tuple,
> 	     enum ip_nat_manip_type maniptype,
>@@ -74,6 +76,10 @@ udp_unique_tuple(struct ip_conntrack_tup
> 		range_size = ntohs(range->max.udp.port) - min + 1;
> 	}
>
>+	/* Start from random port to avoid prediction */
>+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
>+		get_random_bytes(&port,sizeof(port));
>+	}
> 	for (i = 0; i < range_size; i++, port++) {
> 		*portptr = htons(min + port % range_size);
> 		if (!ip_nat_used_tuple(tuple, conntrack))

Do we want get_random_bytes(), or would net_random() suffice?



	-`J'
-- 

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

* Resend [Patch 2/2] iptables: add random option to SNAT
  2007-01-12 22:53 ` Jan Engelhardt
@ 2007-01-13 12:06   ` Eric Leblond
  2007-01-13 21:00   ` Resend [Patch 1/2] Avoid direct connections between NATed hosts Eric Leblond
  1 sibling, 0 replies; 14+ 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] 14+ messages in thread

* Resend [Patch 1/2] Avoid direct connections between NATed hosts
  2007-01-12 22:53 ` Jan Engelhardt
  2007-01-13 12:06   ` Resend [Patch 2/2] iptables: add random option to SNAT Eric Leblond
@ 2007-01-13 21:00   ` Eric Leblond
  2007-01-17 12:23     ` Patrick McHardy
  1 sibling, 1 reply; 14+ messages in thread
From: Eric Leblond @ 2007-01-13 21:00 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel


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

Hi,

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.
> 
> Drop the extra { } - various places.

Done

> Do we want get_random_bytes(), or would net_random() suffice?

It seems that net_random() will be hard enough to predict. Thanks for
the idea.

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

[-- Attachment #1.2: 0001-Add-randomness-to-port-selection-in-SNAT.txt --]
[-- Type: text/plain, Size: 6971 bytes --]

Signed-off-by: Eric Leblond <eric@inl.fr>
---
 include/linux/netfilter_ipv4/ip_nat.h |    1 +
 include/net/netfilter/nf_nat.h        |    1 +
 net/ipv4/netfilter/ip_nat_core.c      |   12 ++++++++++--
 net/ipv4/netfilter/ip_nat_proto_tcp.c |    5 +++++
 net/ipv4/netfilter/ip_nat_proto_udp.c |    5 +++++
 net/ipv4/netfilter/nf_nat_core.c      |   12 ++++++++++--
 net/ipv4/netfilter/nf_nat_proto_tcp.c |    4 ++++
 net/ipv4/netfilter/nf_nat_proto_udp.c |    2 ++
 8 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
index bdf5536..bbca89a 100644
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
 
 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
+#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */
 
 /* NAT sequence number modifications */
 struct ip_nat_seq {
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index 61c6206..bc57dd7 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
 
 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
+#define IP_NAT_RANGE_PROTO_RANDOM 4
 
 /* NAT sequence number modifications */
 struct nf_nat_seq {
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9d1a517..5e08c2b 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -246,8 +246,9 @@ get_unique_tuple(struct ip_conntrack_tup
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		if (find_appropriate_src(orig_tuple, tuple, range)) {
 			DEBUGP("get_unique_tuple: Found current src map\n");
-			if (!ip_nat_used_tuple(tuple, conntrack))
-				return;
+			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
+				if (!ip_nat_used_tuple(tuple, conntrack))
+					return;
 		}
 	}
 
@@ -261,6 +262,13 @@ get_unique_tuple(struct ip_conntrack_tup
 
 	proto = ip_nat_proto_find_get(orig_tuple->dst.protonum);
 
+	/* Change protocol info to have some randomization */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		proto->unique_tuple(tuple, range, maniptype, conntrack);
+		ip_nat_proto_put(proto);
+		return;
+	}
+
 	/* Only bother mapping if it's not already in range and unique */
 	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
 	     || proto->in_range(tuple, maniptype, &range->min, &range->max))
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index b586d18..154a4f7 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -18,6 +18,8 @@ #include <linux/netfilter_ipv4/ip_nat_ru
 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
 #include <linux/netfilter_ipv4/ip_nat_core.h>
 
+#include <linux/random.h>
+
 static int
 tcp_in_range(const struct ip_conntrack_tuple *tuple,
 	     enum ip_nat_manip_type maniptype,
@@ -75,6 +77,9 @@ tcp_unique_tuple(struct ip_conntrack_tup
 		range_size = ntohs(range->max.tcp.port) - min + 1;
 	}
 
+	/* Start from random port to avoid prediction */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port = (u_int16_t) net_random();
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!ip_nat_used_tuple(tuple, conntrack)) {
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 5ced087..b87ed20 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -18,6 +18,8 @@ #include <linux/netfilter_ipv4/ip_nat_co
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
 
+#include <linux/random.h>
+
 static int
 udp_in_range(const struct ip_conntrack_tuple *tuple,
 	     enum ip_nat_manip_type maniptype,
@@ -74,6 +76,9 @@ udp_unique_tuple(struct ip_conntrack_tup
 		range_size = ntohs(range->max.udp.port) - min + 1;
 	}
 
+	/* Start from random port to avoid prediction */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port = (u_int16_t) net_random();
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!ip_nat_used_tuple(tuple, conntrack))
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 86a9227..998b255 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -254,8 +254,9 @@ get_unique_tuple(struct nf_conntrack_tup
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		if (find_appropriate_src(orig_tuple, tuple, range)) {
 			DEBUGP("get_unique_tuple: Found current src map\n");
-			if (!nf_nat_used_tuple(tuple, ct))
-				return;
+			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
+				if (!nf_nat_used_tuple(tuple, ct))
+					return;
 		}
 	}
 
@@ -269,6 +270,13 @@ get_unique_tuple(struct nf_conntrack_tup
 
 	proto = nf_nat_proto_find_get(orig_tuple->dst.protonum);
 
+	/* Change protocol info to have some randomization */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		proto->unique_tuple(tuple, range, maniptype, ct);
+		nf_nat_proto_put(proto);
+		return;
+	}
+
 	/* Only bother mapping if it's not already in range and unique */
 	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
 	     proto->in_range(tuple, maniptype, &range->min, &range->max)) &&
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index 7e26a7e..ba211ef 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -18,6 +18,8 @@ #include <net/netfilter/nf_nat_rule.h>
 #include <net/netfilter/nf_nat_protocol.h>
 #include <net/netfilter/nf_nat_core.h>
 
+#include <linux/random.h>
+
 static int
 tcp_in_range(const struct nf_conntrack_tuple *tuple,
 	     enum nf_nat_manip_type maniptype,
@@ -75,6 +77,8 @@ tcp_unique_tuple(struct nf_conntrack_tup
 		range_size = ntohs(range->max.tcp.port) - min + 1;
 	}
 
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port = (u_int16_t) net_random();
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!nf_nat_used_tuple(tuple, ct))
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
index ab0ce4c..0ce9b83 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -73,6 +73,8 @@ udp_unique_tuple(struct nf_conntrack_tup
 		range_size = ntohs(range->max.udp.port) - min + 1;
 	}
 
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port = (u_int16_t) net_random();
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!nf_nat_used_tuple(tuple, ct))
-- 
1.4.1


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

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

* Re: [Patch 0/2] Avoid direct connections between NATed hosts
  2007-01-12 17:39     ` Rémi Denis-Courmont
@ 2007-01-17 12:13       ` Patrick McHardy
  0 siblings, 0 replies; 14+ messages in thread
From: Patrick McHardy @ 2007-01-17 12:13 UTC (permalink / raw)
  To: Rémi Denis-Courmont; +Cc: netfilter-devel

Rémi Denis-Courmont wrote:
> Le vendredi 12 janvier 2007 19:20, Patrick McHardy a écrit :
> 
>>Port randomization would still be a useful feature, not to wilfully
>>break skype, but to make spoofing attacks harder. Currently we
>>undo randomization done by the operating system/application. Since
>>its optional I don't see real harm in it.
> 
> 
> Right, randomizing port numbers when they are allocated can make it 
> slightly more difficult to spoof DNS. Does the "regular" socket code 
> picks port at random or not though? And is the port allocation logic 
> shared between socket and NAT code (IMHO it should either be shared or 
> at least be equivalent)? It makes little sense to secure host behind 
> the NAT and not secure yourself; that also imples there should be no 
> need for an iptables option to enable/disable it.

Its not shared, local port allocation is quite different from NAT.

> My concern is with when (and how) Netfilter NAT code allocates a new 
> port number. If the source private-IP/port are identical, the external 
> NATed-IP/port ought be identical too, and certainly not another 
> randomized value.
> 
> With that, you have the advantage of random source port numbers (better 
> spoof protection), while not breaking any NAT-aware P2P app.

Thats impossible to guarantee, since we're mapping many address to
one we might get clashes.

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

* Re: Resend [Patch 1/2] Avoid direct connections between NATed hosts
  2007-01-13 21:00   ` Resend [Patch 1/2] Avoid direct connections between NATed hosts Eric Leblond
@ 2007-01-17 12:23     ` Patrick McHardy
  2007-01-17 15:18       ` Eric Leblond
  0 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2007-01-17 12:23 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, Jan Engelhardt

Eric Leblond wrote:
> diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
> index bdf5536..bbca89a 100644
> --- a/include/linux/netfilter_ipv4/ip_nat.h
> +++ b/include/linux/netfilter_ipv4/ip_nat.h
> @@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
>  
>  #define IP_NAT_RANGE_MAP_IPS 1
>  #define IP_NAT_RANGE_PROTO_SPECIFIED 2
> +#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */
>  
>  /* NAT sequence number modifications */
>  struct ip_nat_seq {
> diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
> index 61c6206..bc57dd7 100644
> --- a/include/net/netfilter/nf_nat.h
> +++ b/include/net/netfilter/nf_nat.h
> @@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
>  
>  #define IP_NAT_RANGE_MAP_IPS 1
>  #define IP_NAT_RANGE_PROTO_SPECIFIED 2
> +#define IP_NAT_RANGE_PROTO_RANDOM 4
>  
>  /* NAT sequence number modifications */
>  struct nf_nat_seq {
> diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
> index 9d1a517..5e08c2b 100644
> --- a/net/ipv4/netfilter/ip_nat_core.c
> +++ b/net/ipv4/netfilter/ip_nat_core.c
> @@ -246,8 +246,9 @@ get_unique_tuple(struct ip_conntrack_tup
>  	if (maniptype == IP_NAT_MANIP_SRC) {
>  		if (find_appropriate_src(orig_tuple, tuple, range)) {
>  			DEBUGP("get_unique_tuple: Found current src map\n");
> -			if (!ip_nat_used_tuple(tuple, conntrack))
> -				return;
> +			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
> +				if (!ip_nat_used_tuple(tuple, conntrack))
> +					return;
>  		}
>  	}
>  
> @@ -261,6 +262,13 @@ get_unique_tuple(struct ip_conntrack_tup
>  
>  	proto = ip_nat_proto_find_get(orig_tuple->dst.protonum);
>  
> +	/* Change protocol info to have some randomization */
> +	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {

This doesn't seem to make much sense for DNAT. Either catch it in
the checkentry functions or avoid some other way.

> +		proto->unique_tuple(tuple, range, maniptype, conntrack);
> +		ip_nat_proto_put(proto);
> +		return;
> +	}
> +
>  	/* Only bother mapping if it's not already in range and unique */
>  	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
>  	     || proto->in_range(tuple, maniptype, &range->min, &range->max))
> diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
> index b586d18..154a4f7 100644
> --- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
> +++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
> @@ -18,6 +18,8 @@ #include <linux/netfilter_ipv4/ip_nat_ru
>  #include <linux/netfilter_ipv4/ip_nat_protocol.h>
>  #include <linux/netfilter_ipv4/ip_nat_core.h>
>  
> +#include <linux/random.h>

Put this next to the other linux/ includes please.

> +
>  static int
>  tcp_in_range(const struct ip_conntrack_tuple *tuple,
>  	     enum ip_nat_manip_type maniptype,
> @@ -75,6 +77,9 @@ tcp_unique_tuple(struct ip_conntrack_tup
>  		range_size = ntohs(range->max.tcp.port) - min + 1;
>  	}
>  
> +	/* Start from random port to avoid prediction */
> +	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
> +		port = (u_int16_t) net_random();

No need to cast, also endianness error (port is __be16).

>  	for (i = 0; i < range_size; i++, port++) {
>  		*portptr = htons(min + port % range_size);
>  		if (!ip_nat_used_tuple(tuple, conntrack)) {

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

* Re: Resend [Patch 1/2] Avoid direct connections between NATed hosts
  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
  0 siblings, 2 replies; 14+ messages in thread
From: Eric Leblond @ 2007-01-17 15:18 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Jan Engelhardt


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

Hi,

This patch is a try to apply all the modifications you have asked.

BR,

Le mercredi 17 janvier 2007 à 13:23 +0100, Patrick McHardy a écrit :
> Eric Leblond wrote:
> > diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
> > index bdf5536..bbca89a 100644
> > --- a/include/linux/netfilter_ipv4/ip_nat.h
> > +++ b/include/linux/netfilter_ipv4/ip_nat.h
> > @@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
> >  
> >  #define IP_NAT_RANGE_MAP_IPS 1
> >  #define IP_NAT_RANGE_PROTO_SPECIFIED 2
> > +#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */
> >  
> >  /* NAT sequence number modifications */
> >  struct ip_nat_seq {
> > diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
> > index 61c6206..bc57dd7 100644
> > --- a/include/net/netfilter/nf_nat.h
> > +++ b/include/net/netfilter/nf_nat.h
> > @@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
> >  
> >  #define IP_NAT_RANGE_MAP_IPS 1
> >  #define IP_NAT_RANGE_PROTO_SPECIFIED 2
> > +#define IP_NAT_RANGE_PROTO_RANDOM 4
> >  
> >  /* NAT sequence number modifications */
> >  struct nf_nat_seq {
> > diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
> > index 9d1a517..5e08c2b 100644
> > --- a/net/ipv4/netfilter/ip_nat_core.c
> > +++ b/net/ipv4/netfilter/ip_nat_core.c
> > @@ -246,8 +246,9 @@ get_unique_tuple(struct ip_conntrack_tup
> >  	if (maniptype == IP_NAT_MANIP_SRC) {
> >  		if (find_appropriate_src(orig_tuple, tuple, range)) {
> >  			DEBUGP("get_unique_tuple: Found current src map\n");
> > -			if (!ip_nat_used_tuple(tuple, conntrack))
> > -				return;
> > +			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
> > +				if (!ip_nat_used_tuple(tuple, conntrack))
> > +					return;
> >  		}
> >  	}
> >  
> > @@ -261,6 +262,13 @@ get_unique_tuple(struct ip_conntrack_tup
> >  
> >  	proto = ip_nat_proto_find_get(orig_tuple->dst.protonum);
> >  
> > +	/* Change protocol info to have some randomization */
> > +	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
> 
> This doesn't seem to make much sense for DNAT. Either catch it in
> the checkentry functions or avoid some other way.
> 
> > +		proto->unique_tuple(tuple, range, maniptype, conntrack);
> > +		ip_nat_proto_put(proto);
> > +		return;
> > +	}
> > +
> >  	/* Only bother mapping if it's not already in range and unique */
> >  	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
> >  	     || proto->in_range(tuple, maniptype, &range->min, &range->max))
> > diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
> > index b586d18..154a4f7 100644
> > --- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
> > +++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
> > @@ -18,6 +18,8 @@ #include <linux/netfilter_ipv4/ip_nat_ru
> >  #include <linux/netfilter_ipv4/ip_nat_protocol.h>
> >  #include <linux/netfilter_ipv4/ip_nat_core.h>
> >  
> > +#include <linux/random.h>
> 
> Put this next to the other linux/ includes please.
> 
> > +
> >  static int
> >  tcp_in_range(const struct ip_conntrack_tuple *tuple,
> >  	     enum ip_nat_manip_type maniptype,
> > @@ -75,6 +77,9 @@ tcp_unique_tuple(struct ip_conntrack_tup
> >  		range_size = ntohs(range->max.tcp.port) - min + 1;
> >  	}
> >  
> > +	/* Start from random port to avoid prediction */
> > +	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
> > +		port = (u_int16_t) net_random();
> 
> No need to cast, also endianness error (port is __be16).
> 
> >  	for (i = 0; i < range_size; i++, port++) {
> >  		*portptr = htons(min + port % range_size);
> >  		if (!ip_nat_used_tuple(tuple, conntrack)) {

[-- Attachment #1.2: 0001-Avoid-direct-connections-between-NATed-hosts.txt --]
[-- Type: text/plain, Size: 8219 bytes --]

From 3c85074785935c8dfea41915908c196d98e6c47d Mon Sep 17 00:00:00 2001
From: Eric Leblond <eric@inl.fr>
Date: Wed, 17 Jan 2007 16:14:23 +0100
Subject: [PATCH] Avoid direct connections between NATed hosts

This patch adds the capability to randomize ports choice
during NAT. This blocks some software using port prediction
to established connections between NATed hosts.
Signed-off-by: Eric Leblond <eric@ice-age.(none)>
---
 include/linux/netfilter_ipv4/ip_nat.h |    1 +
 include/net/netfilter/nf_nat.h        |    1 +
 net/ipv4/netfilter/ip_nat_core.c      |   12 ++++++++++--
 net/ipv4/netfilter/ip_nat_proto_tcp.c |    4 ++++
 net/ipv4/netfilter/ip_nat_proto_udp.c |    4 ++++
 net/ipv4/netfilter/ip_nat_rule.c      |    4 ++++
 net/ipv4/netfilter/nf_nat_core.c      |   12 ++++++++++--
 net/ipv4/netfilter/nf_nat_proto_tcp.c |    3 +++
 net/ipv4/netfilter/nf_nat_proto_udp.c |    3 +++
 net/ipv4/netfilter/nf_nat_rule.c      |    4 ++++
 10 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
index bdf5536..bbca89a 100644
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
 
 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
+#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */
 
 /* NAT sequence number modifications */
 struct ip_nat_seq {
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index 61c6206..bc57dd7 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -16,6 +16,7 @@ #define HOOK2MANIP(hooknum) ((hooknum) !
 
 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
+#define IP_NAT_RANGE_PROTO_RANDOM 4
 
 /* NAT sequence number modifications */
 struct nf_nat_seq {
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9d1a517..5e08c2b 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -246,8 +246,9 @@ get_unique_tuple(struct ip_conntrack_tup
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		if (find_appropriate_src(orig_tuple, tuple, range)) {
 			DEBUGP("get_unique_tuple: Found current src map\n");
-			if (!ip_nat_used_tuple(tuple, conntrack))
-				return;
+			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
+				if (!ip_nat_used_tuple(tuple, conntrack))
+					return;
 		}
 	}
 
@@ -261,6 +262,13 @@ get_unique_tuple(struct ip_conntrack_tup
 
 	proto = ip_nat_proto_find_get(orig_tuple->dst.protonum);
 
+	/* Change protocol info to have some randomization */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		proto->unique_tuple(tuple, range, maniptype, conntrack);
+		ip_nat_proto_put(proto);
+		return;
+	}
+
 	/* Only bother mapping if it's not already in range and unique */
 	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)
 	     || proto->in_range(tuple, maniptype, &range->min, &range->max))
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index b586d18..78ff1bb 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/random.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -75,6 +76,9 @@ tcp_unique_tuple(struct ip_conntrack_tup
 		range_size = ntohs(range->max.tcp.port) - min + 1;
 	}
 
+	/* Start from random port to avoid prediction */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port =  __cpu_to_be16(net_random());
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!ip_nat_used_tuple(tuple, conntrack)) {
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 5ced087..752a292 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/random.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
 #include <linux/udp.h>
@@ -74,6 +75,9 @@ udp_unique_tuple(struct ip_conntrack_tup
 		range_size = ntohs(range->max.udp.port) - min + 1;
 	}
 
+	/* Start from random port to avoid prediction */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port = __cpu_to_be16(net_random());
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!ip_nat_used_tuple(tuple, conntrack))
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
index a176aa3..6ebaad3 100644
--- a/net/ipv4/netfilter/ip_nat_rule.c
+++ b/net/ipv4/netfilter/ip_nat_rule.c
@@ -193,6 +193,10 @@ static int ipt_dnat_checkentry(const cha
 		printk("DNAT: multiple ranges no longer supported\n");
 		return 0;
 	}
+	if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		printk("DNAT: port randomization not supported\n");
+		return 0;
+	}
 	return 1;
 }
 
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 86a9227..998b255 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -254,8 +254,9 @@ get_unique_tuple(struct nf_conntrack_tup
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		if (find_appropriate_src(orig_tuple, tuple, range)) {
 			DEBUGP("get_unique_tuple: Found current src map\n");
-			if (!nf_nat_used_tuple(tuple, ct))
-				return;
+			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
+				if (!nf_nat_used_tuple(tuple, ct))
+					return;
 		}
 	}
 
@@ -269,6 +270,13 @@ get_unique_tuple(struct nf_conntrack_tup
 
 	proto = nf_nat_proto_find_get(orig_tuple->dst.protonum);
 
+	/* Change protocol info to have some randomization */
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		proto->unique_tuple(tuple, range, maniptype, ct);
+		nf_nat_proto_put(proto);
+		return;
+	}
+
 	/* Only bother mapping if it's not already in range and unique */
 	if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
 	     proto->in_range(tuple, maniptype, &range->min, &range->max)) &&
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index 7e26a7e..f0e37f0 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/random.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 
@@ -75,6 +76,8 @@ tcp_unique_tuple(struct nf_conntrack_tup
 		range_size = ntohs(range->max.tcp.port) - min + 1;
 	}
 
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port =  __cpu_to_be16(net_random());
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!nf_nat_used_tuple(tuple, ct))
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
index ab0ce4c..8a46521 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/random.h>
 #include <linux/ip.h>
 #include <linux/udp.h>
 
@@ -73,6 +74,8 @@ udp_unique_tuple(struct nf_conntrack_tup
 		range_size = ntohs(range->max.udp.port) - min + 1;
 	}
 
+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
+		port =  __cpu_to_be16(net_random());
 	for (i = 0; i < range_size; i++, port++) {
 		*portptr = htons(min + port % range_size);
 		if (!nf_nat_used_tuple(tuple, ct))
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index b868ee0..3745efe 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -226,6 +226,10 @@ static int ipt_dnat_checkentry(const cha
 		printk("DNAT: multiple ranges no longer supported\n");
 		return 0;
 	}
+	if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM) {
+		printk("DNAT: port randomization not supported\n");
+		return 0;
+	}
 	return 1;
 }
 
-- 
1.4.1


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

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

* Re: Resend [Patch 1/2] Avoid direct connections between NATed hosts
  2007-01-17 15:18       ` Eric Leblond
@ 2007-01-19 15:36         ` Patrick McHardy
  2007-01-26 14:00         ` Patrick McHardy
  1 sibling, 0 replies; 14+ messages in thread
From: Patrick McHardy @ 2007-01-19 15:36 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, Jan Engelhardt

Eric Leblond wrote:
>>> 
>>>+	/* Start from random port to avoid prediction */
>>>+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
>>>+		port = (u_int16_t) net_random();
>>
>>No need to cast, also endianness error (port is __be16).


>>>diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
>>>index b586d18..78ff1bb 100644
>>>--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
>>>+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
>>>@@ -8,6 +8,7 @@
>>> 
>>> #include <linux/types.h>
>>> #include <linux/init.h>
>>>+#include <linux/random.h>
>>> #include <linux/netfilter.h>
>>> #include <linux/ip.h>
>>> #include <linux/tcp.h>
>>>@@ -75,6 +76,9 @@ tcp_unique_tuple(struct ip_conntrack_tup
>>> 		range_size = ntohs(range->max.tcp.port) - min + 1;
>>> 	}
>>> 
>>>+	/* Start from random port to avoid prediction */
>>>+	if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
>>>+		port =  __cpu_to_be16(net_random());


Sorry that was my mistake, port is host endian, I can fix that before
applying. Other than that it looks fine, if there are no objections
from other people I'm going to apply it this weekend.

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

* Re: Resend [Patch 1/2] Avoid direct connections between NATed hosts
  2007-01-17 15:18       ` Eric Leblond
  2007-01-19 15:36         ` Patrick McHardy
@ 2007-01-26 14:00         ` Patrick McHardy
  1 sibling, 0 replies; 14+ messages in thread
From: Patrick McHardy @ 2007-01-26 14:00 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel, Jan Engelhardt

Eric Leblond wrote:
> This patch is a try to apply all the modifications you have asked.

Queued for 2.6.21, thanks Eric.

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

end of thread, other threads:[~2007-01-26 14:00 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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   ` Resend [Patch 2/2] iptables: add random option to SNAT Eric Leblond
2007-01-13 21:00   ` Resend [Patch 1/2] Avoid direct connections between NATed hosts 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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.