netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Leblond <eric@inl.fr>
To: Patrick McHardy <kaber@trash.net>
Cc: netfilter-devel@lists.netfilter.org,
	Jan Engelhardt <jengelh@linux01.gwdg.de>
Subject: Re: Resend [Patch 1/2] Avoid direct connections between NATed hosts
Date: Wed, 17 Jan 2007 16:18:20 +0100	[thread overview]
Message-ID: <1169047100.26570.1.camel@localhost.localdomain> (raw)
In-Reply-To: <45AE153F.6010105@trash.net>


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

  reply	other threads:[~2007-01-17 15:18 UTC|newest]

Thread overview: 14+ 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   ` 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 [this message]
2007-01-19 15:36         ` Patrick McHardy
2007-01-26 14:00         ` 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=1169047100.26570.1.camel@localhost.localdomain \
    --to=eric@inl.fr \
    --cc=jengelh@linux01.gwdg.de \
    --cc=kaber@trash.net \
    --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).