* [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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ messages in thread
end of thread, other threads:[~2007-02-24 14:21 UTC | newest]
Thread overview: 22+ 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
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
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.