2020447 IPFilter's NAT can undo name server random port selection

This commit is contained in:
darrenr 2008-07-24 09:37:57 +00:00
parent 474699860b
commit 9f0bfbf3da
15 changed files with 103 additions and 35 deletions

17
dist/ipf/ip_fil.c vendored
View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_fil.c,v 1.15 2008/05/20 07:08:06 darrenr Exp $ */
/* $NetBSD: ip_fil.c,v 1.16 2008/07/24 09:37:57 darrenr Exp $ */
/*
* Copyright (C) 1993-2001 by Darren Reed.
@ -816,3 +816,18 @@ int ipfsync()
{
return 0;
}
u_32_t ipf_random()
{
static int seeded = 0;
/*
* Choose a non-random seed so that "randomness" can be "tested."
*/
if (seeded == 0) {
srand(0);
seeded = 1;
}
return rand();
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: printnat.c,v 1.1.1.7 2008/05/20 06:45:03 darrenr Exp $ */
/* $NetBSD: printnat.c,v 1.2 2008/07/24 09:37:58 darrenr Exp $ */
/*
* Copyright (C) 2002-2005 by Darren Reed.
@ -217,6 +217,8 @@ int opts;
putchar(' ');
printproto(pr, np->in_p, np);
}
if (np->in_flags & IPN_SEQUENTIAL)
printf(" sequential");
printf("\n");
if (opts & OPT_DEBUG) {
struct in_addr nip;

View File

@ -1 +1 @@
map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000
map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 sequential

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipnat_y.y,v 1.16 2008/05/20 07:08:07 darrenr Exp $ */
/* $NetBSD: ipnat_y.y,v 1.17 2008/07/24 09:37:58 darrenr Exp $ */
/*
* Copyright (C) 2001-2006 by Darren Reed.
@ -95,7 +95,7 @@ static void setnatproto __P((int));
%token IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY
%token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY
%token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG
%token IPNY_TLATE
%token IPNY_TLATE IPNY_SEQUENTIAL
%type <port> portspec
%type <num> hexnumber compare range proto
%type <ipa> hostname ipv4
@ -422,11 +422,11 @@ otherifname:
;
mapport:
IPNY_PORTMAP tcpudp portspec ':' portspec
IPNY_PORTMAP tcpudp portspec ':' portspec randport
{ nat->in_pmin = htons($3);
nat->in_pmax = htons($5);
}
| IPNY_PORTMAP tcpudp IPNY_AUTO
| IPNY_PORTMAP tcpudp IPNY_AUTO randport
{ nat->in_flags |= IPN_AUTOPORTMAP;
nat->in_pmin = htons(1024);
nat->in_pmax = htons(65535);
@ -446,6 +446,10 @@ mapport:
}
;
randport:
| IPNY_SEQUENTIAL { nat->in_flags |= IPN_SEQUENTIAL; }
;
sobject:
saddr
| saddr port portstuff { nat->in_sport = $3.p1;
@ -519,6 +523,7 @@ rdroptions:
nattag: | IPNY_TAG YY_STR { strncpy(nat->in_tag.ipt_tag, $2,
sizeof(nat->in_tag.ipt_tag));
}
rr: | IPNY_ROUNDROBIN { nat->in_flags |= IPN_ROUNDR; }
;
@ -647,6 +652,7 @@ static wordtab_t yywords[] = {
{ "range", IPNY_RANGE },
{ "rdr", IPNY_RDR },
{ "round-robin",IPNY_ROUNDROBIN },
{ "sequential", IPNY_SEQUENTIAL },
{ "sticky", IPNY_STICKY },
{ "tag", IPNY_TAG },
{ "tcp", IPNY_TCP },

View File

@ -1 +1 @@
map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000
map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 sequential

View File

@ -1,4 +1,4 @@
map zx0 10.1.1.1/32 -> 10.2.2.2/32 portmap tcp 10000:20000
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000
map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001
map zx0 10.1.1.1/32 -> 10.2.2.2/32 portmap tcp 10000:20000 sequential
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential
map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential

View File

@ -1,6 +1,6 @@
map zx0 10.1.1.1/32 -> 10.2.2.2/32
map zx0 from 10.1.1.0/24 to 10.1.0.0/16 -> 10.3.4.5/32
map zx0 from 10.1.1.0/24 ! to 10.1.0.0/16 -> 10.3.4.0/24
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000
map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential
map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential
map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential

View File

@ -1,3 +1,3 @@
map df0 from 2.2.2.2/32 port 20000 >< 25000 to any -> 6.6.6.8/32 portmap udp 2000:2500
map df0 from 2.2.2.2/32 port 2000 >< 2500 to any -> 6.6.6.7/32 portmap udp 20000:25000
map df0 from 2.2.2.2/32 port 20000 >< 25000 to any -> 6.6.6.8/32 portmap udp 2000:2500 sequential
map df0 from 2.2.2.2/32 port 2000 >< 2500 to any -> 6.6.6.7/32 portmap udp 20000:25000 sequential
map df0 from 2.2.2.2/32 to any -> 6.6.6.6/32

View File

@ -1 +1 @@
map xl0 10.0.0.0/8 -> 1.1.1.1/32 portmap tcp/udp 40000:60000
map xl0 10.0.0.0/8 -> 1.1.1.1/32 portmap tcp/udp 40000:60000 sequential

View File

@ -1 +1 @@
map df0 2.2.2.2/32 -> 6.6.6.6/32 portmap tcp/udp 40000:60000
map df0 2.2.2.2/32 -> 6.6.6.6/32 portmap tcp/udp 40000:60000 sequential

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_compat.h,v 1.21 2008/06/08 11:31:28 darrenr Exp $ */
/* $NetBSD: ip_compat.h,v 1.22 2008/07/24 09:37:58 darrenr Exp $ */
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
@ -208,6 +208,8 @@ typedef unsigned int u_32_t;
# define U_32_T 1
# ifdef _KERNEL
# define NEED_LOCAL_RAND 1
# define ipf_random arc4random
# define KRWLOCK_T krwlock_t
# define KMUTEX_T kmutex_t
@ -338,6 +340,7 @@ typedef mblk_t mb_t;
typedef struct uio uio_t;
# endif
typedef int ioctlcmd_t;
typedef uint8_t u_int8_t;
# define OS_RECOGNISED 1
@ -568,6 +571,8 @@ typedef struct {
# endif
# ifdef _KERNEL
# define NEED_LOCAL_RAND 1
# define ipf_random arc4random
# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \
(x)++; MUTEX_EXIT(&ipf_rw); }
# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \
@ -664,6 +669,8 @@ typedef struct mbuf mb_t;
# include <sys/sysmacros.h>
# ifdef _KERNEL
# define NEED_LOCAL_RAND 1
# define ipf_random arc4random
# define KMUTEX_T simple_lock_data_t
# define KRWLOCK_T lock_data_t
# include <net/net_globals.h>
@ -785,6 +792,8 @@ typedef unsigned int u_32_t;
# endif
# endif
# define ipf_random arc4random
# ifdef _KERNEL
# if (__NetBSD_Version__ >= 499000000)
typedef char * caddr_t;
@ -832,6 +841,11 @@ typedef u_int32_t u_32_t;
/* F R E E B S D */
/* ----------------------------------------------------------------------- */
#ifdef __FreeBSD__
# if (__FreeBSD_version < 400000)
# define NEED_LOCAL_RAND 1
# else
# define ipf_random arc4random
# endif
# if defined(_KERNEL)
# if (__FreeBSD_version >= 500000)
# include "opt_bpf.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_fil.h,v 1.16 2008/05/20 07:08:07 darrenr Exp $ */
/* $NetBSD: ip_fil.h,v 1.17 2008/07/24 09:37:58 darrenr Exp $ */
/*
* Copyright (C) 1993-2001, 2003 by Darren Reed.
@ -1522,6 +1522,12 @@ extern void ipf_freetoken __P((ipftoken_t *));
extern int ipf_deltoken __P((int,int, void *));
extern int ipfsync __P((void));
extern int ipf_genericiter __P((void *, int, void *));
#ifndef ipf_random
extern u_32_t ipf_random __P((void));
#endif
#ifdef NEED_LOCAL_RAND
extern void ipf_rand_push __P((void *, int));
#endif
extern int fr_running;
extern u_long fr_frouteok[2];

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_nat.c,v 1.36 2008/05/20 07:08:08 darrenr Exp $ */
/* $NetBSD: ip_nat.c,v 1.37 2008/07/24 09:37:58 darrenr Exp $ */
/*
* Copyright (C) 1995-2003 by Darren Reed.
@ -118,10 +118,10 @@ extern struct ifnet vpnif;
#if !defined(lint)
#if defined(__NetBSD__)
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip_nat.c,v 1.36 2008/05/20 07:08:08 darrenr Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip_nat.c,v 1.37 2008/07/24 09:37:58 darrenr Exp $");
#else
static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 1.36 2008/05/20 07:08:08 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_nat.c,v 1.37 2008/07/24 09:37:58 darrenr Exp $";
#endif
#endif
@ -1698,6 +1698,9 @@ int logtype;
if (logtype != 0 && nat_logging != 0)
nat_log(nat, logtype);
#if defined(NEED_LOCAL_RAND) && defined(_KERNEL)
ipf_rand_push(nat, sizeof(*nat));
#endif
/*
* Take it as a general indication that all the pointers are set if
@ -2048,7 +2051,13 @@ natinfo_t *ni;
/*
* Standard port translation. Select next port.
*/
port = htons(np->in_pnext++);
if (np->in_flags & IPN_SEQUENTIAL) {
port = htons(np->in_pnext);
} else {
port = ipf_random() % (ntohs(np->in_pmax) -
ntohs(np->in_pmin));
}
np->in_pnext++;
if (np->in_pnext > ntohs(np->in_pmax)) {
np->in_pnext = ntohs(np->in_pmin);
@ -3815,7 +3824,7 @@ u_32_t *passp;
READ_ENTER(&ipf_nat);
if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) &&
if (((fin->fin_flx & FI_ICMPERR) != 0) &&
(nat = nat_icmperror(fin, &nflags, NAT_OUTBOUND)))
/*EMPTY*/;
else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin)))
@ -4128,7 +4137,7 @@ u_32_t *passp;
READ_ENTER(&ipf_nat);
if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) &&
if (((fin->fin_flx & FI_ICMPERR) != 0) &&
(nat = nat_icmperror(fin, &nflags, NAT_INBOUND)))
/*EMPTY*/;
else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin)))

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_nat.h,v 1.13 2007/10/02 06:15:12 martti Exp $ */
/* $NetBSD: ip_nat.h,v 1.14 2008/07/24 09:37:58 darrenr Exp $ */
/*
* Copyright (C) 1995-2001, 2003 by Darren Reed.
@ -6,7 +6,7 @@
* See the IPFILTER.LICENCE file for details on licencing.
*
* @(#)ip_nat.h 1.5 2/4/96
* $Id: ip_nat.h,v 1.13 2007/10/02 06:15:12 martti Exp $
* $Id: ip_nat.h,v 1.14 2008/07/24 09:37:58 darrenr Exp $
*/
#ifndef __IP_NAT_H__
@ -255,9 +255,11 @@ typedef struct ipnat {
#define IPN_FIXEDDPORT 0x200000
#define IPN_FINDFORWARD 0x400000
#define IPN_IN 0x800000
#define IPN_SEQUENTIAL 0x1000000
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\
IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY)
IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\
IPN_SEQUENTIAL)
/*
* Values for in_redir

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_state.c,v 1.32 2008/06/01 22:26:11 darrenr Exp $ */
/* $NetBSD: ip_state.c,v 1.33 2008/07/24 09:37:58 darrenr Exp $ */
/*
* Copyright (C) 1995-2003 by Darren Reed.
@ -114,10 +114,10 @@ struct file;
#if !defined(lint)
#if defined(__NetBSD__)
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.32 2008/06/01 22:26:11 darrenr Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip_state.c,v 1.33 2008/07/24 09:37:58 darrenr Exp $");
#else
static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 1.32 2008/06/01 22:26:11 darrenr Exp $";
static const char rcsid[] = "@(#)$Id: ip_state.c,v 1.33 2008/07/24 09:37:58 darrenr Exp $";
#endif
#endif
@ -206,6 +206,9 @@ ipstate_t *ips_list = NULL;
/* ------------------------------------------------------------------------ */
int fr_stateinit()
{
#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL)
struct timeval tv;
#endif
int i;
KMALLOCS(ips_table, ipstate_t **, fr_statesize * sizeof(ipstate_t *));
@ -216,20 +219,27 @@ int fr_stateinit()
KMALLOCS(ips_seed, u_long *, fr_statesize * sizeof(*ips_seed));
if (ips_seed == NULL)
return -2;
#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL)
tv.tv_sec = 0;
GETKTIME(&tv);
#endif
for (i = 0; i < fr_statesize; i++) {
/*
* XXX - ips_seed[X] should be a random number of sorts.
*/
#if (__FreeBSD_version >= 400000)
#if !defined(NEED_LOCAL_RAND) && defined(_KERNEL)
ips_seed[i] = arc4random();
#else
ips_seed[i] = ((u_long)ips_seed + i) * fr_statesize;
ips_seed[i] ^= 0xa5a55a5a;
ips_seed[i] += tv.tv_sec;
ips_seed[i] *= (u_long)ips_seed;
ips_seed[i] ^= 0x5a5aa5a5;
ips_seed[i] *= fr_statemax;
#endif
}
#if defined(NEED_LOCAL_RAND) && defined(_KERNEL)
ipf_rand_push(ips_seed, fr_statesize * sizeof(*ips_seed));
#endif
/* fill icmp reply type table */
for (i = 0; i <= ICMP_MAXTYPE; i++)
@ -3236,6 +3246,10 @@ int why;
(void) fr_derefrule(&is->is_rule);
}
#if defined(NEED_LOCAL_RAND) && defined(_KERNEL)
ipf_rand_push(is, sizeof(*is));
#endif
MUTEX_DESTROY(&is->is_lock);
KFREE(is);
ips_num--;