Skip to content

Commit

Permalink
[NETFILTER]: NAT: optional source port randomization support
Browse files Browse the repository at this point in the history
This patch adds support to NAT to randomize source ports.

Signed-off-by: Eric Leblond <eric@inl.fr>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Leblond authored and David S. Miller committed Feb 8, 2007
1 parent cdd289a commit 41f4689
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/linux/netfilter_ipv4/ip_nat.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum ip_nat_manip_type

#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 {
Expand Down
1 change: 1 addition & 0 deletions include/net/netfilter/nf_nat.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum nf_nat_manip_type

#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 {
Expand Down
12 changes: 10 additions & 2 deletions net/ipv4/netfilter/ip_nat_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,9 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
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;
}
}

Expand All @@ -261,6 +262,13 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,

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))
Expand Down
5 changes: 5 additions & 0 deletions net/ipv4/netfilter/ip_nat_proto_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -75,6 +76,10 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple,
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 = net_random();

for (i = 0; i < range_size; i++, port++) {
*portptr = htons(min + port % range_size);
if (!ip_nat_used_tuple(tuple, conntrack)) {
Expand Down
5 changes: 5 additions & 0 deletions net/ipv4/netfilter/ip_nat_proto_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -74,6 +75,10 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple,
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 = net_random();

for (i = 0; i < range_size; i++, port++) {
*portptr = htons(min + port % range_size);
if (!ip_nat_used_tuple(tuple, conntrack))
Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/netfilter/ip_nat_rule.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ static int ipt_dnat_checkentry(const char *tablename,
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;
}

Expand Down
12 changes: 10 additions & 2 deletions net/ipv4/netfilter/nf_nat_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,9 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
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;
}
}

Expand All @@ -269,6 +270,13 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,

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)) &&
Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/netfilter/nf_nat_proto_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <linux/types.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/ip.h>
#include <linux/tcp.h>

Expand Down Expand Up @@ -75,6 +76,9 @@ tcp_unique_tuple(struct nf_conntrack_tuple *tuple,
range_size = ntohs(range->max.tcp.port) - min + 1;
}

if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
port = net_random();

for (i = 0; i < range_size; i++, port++) {
*portptr = htons(min + port % range_size);
if (!nf_nat_used_tuple(tuple, ct))
Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/netfilter/nf_nat_proto_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <linux/types.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/ip.h>
#include <linux/udp.h>

Expand Down Expand Up @@ -73,6 +74,9 @@ udp_unique_tuple(struct nf_conntrack_tuple *tuple,
range_size = ntohs(range->max.udp.port) - min + 1;
}

if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
port = net_random();

for (i = 0; i < range_size; i++, port++) {
*portptr = htons(min + port % range_size);
if (!nf_nat_used_tuple(tuple, ct))
Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/netfilter/nf_nat_rule.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ static int ipt_dnat_checkentry(const char *tablename,
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;
}

Expand Down

0 comments on commit 41f4689

Please sign in to comment.