|
View:
New views
8 Messages
—
Rating Filter:
Alert me
|
|
|
randomize source portAs a quick test, I did the following:
--- in_pcb.c 5 May 2008 17:11:17 -0000 1.125 +++ in_pcb.c 11 Jul 2008 15:33:49 -0000 @@ -332,6 +332,8 @@ mymax = swp; } + *lastport = mymax - (arc4random() % (mymax - mymin)); + lport = *lastport - 1; for (cnt = mymax - mymin + 1; cnt; cnt--, lport--) { if (lport < mymin || lport > mymax) With default sysctl: net.inet.ip.anonportmin = 49152 net.inet.ip.anonportmax = 65535 Using gethostbyname2(3), I did many lookups (some simultaneously) to one of my local nameservers. Before my patch, the source port counted down from 65026 to 64845. After my patch, the source port, I didn't see any noticable sequence of counting down, such as: 52362 59398 64223 51205 55882 ... 50004 64005 64193 51223 53918 And the range of 49202 to 65491. By the way, FreeBSD has these sysctl tunables: net.inet.ip.portrange.randomized Enable random port allocation. (Default is on.) net.inet.ip.portrange.randomcps Maximum number of random port allocations in last second before switching to a sequental one. (Default is 10.) net.inet.ip.portrange.randomtime Minimum time to keep sequental port allocation (while randomcps is not reached) before switching back to a random one. (Default is 45 seconds.) |
|
|
Re: randomize source portOn Fri, 11 Jul 2008 11:00:21 -0500 (CDT)
"Jeremy C. Reed" <reed@...> wrote: > As a quick test, I did the following: > > --- in_pcb.c 5 May 2008 17:11:17 -0000 1.125 > +++ in_pcb.c 11 Jul 2008 15:33:49 -0000 > @@ -332,6 +332,8 @@ > mymax = swp; > } > > + *lastport = mymax - (arc4random() % (mymax - mymin)); > + > lport = *lastport - 1; > for (cnt = mymax - mymin + 1; cnt; cnt--, lport--) { > if (lport < mymin || lport > mymax) > > program that just counted how many UDP ports it could bind to in ten seconds? I expect some impact, but not a big one; arc4 is very cheap, but measurement is always good. More seriously -- when at boot time does urandom have enough entropy to seed the PRNG? I've had problems on some server systems with things like that. --Steve Bellovin, http://www.cs.columbia.edu/~smb |
|
|
Re: randomize source portOn Fri, Jul 11, 2008 at 11:00:21AM -0500, Jeremy C. Reed wrote:
> As a quick test, I did the following: I'm not sure if directly randomising the port is a good idea. I think it should at least be a random shuffle for the same reason that the TCP sequence numbers are not using a direct PRNG. Note that a random shuffle also avoids most of the motivation for moving to a sequential numbers, at least if short living connections are concerned. Joerg |
|
|
Re: randomize source portOn Fri, 11 Jul 2008 18:22:45 +0200
Joerg Sonnenberger <joerg@...> wrote: > On Fri, Jul 11, 2008 at 11:00:21AM -0500, Jeremy C. Reed wrote: > > As a quick test, I did the following: > > I'm not sure if directly randomising the port is a good idea. > I think it should at least be a random shuffle for the same reason > that the TCP sequence numbers are not using a direct PRNG. I don't see the similarity. For sequence numbers, there's a requirement in the RFC for a 4 microsecond counter; there's also analysis concerning defense against old packets lying around the network. The possible issue here is consecutive use of the same port number; I don't think it's a real concern. > Note that > a random shuffle also avoids most of the motivation for moving to a > sequential numbers, at least if short living connections are > concerned. > I don't understand. --Steve Bellovin, http://www.cs.columbia.edu/~smb |
|
|
Re: randomize source portOn Fri, Jul 11, 2008 at 12:46:24PM -0400, Steven M. Bellovin wrote:
> On Fri, 11 Jul 2008 18:22:45 +0200 > Joerg Sonnenberger <joerg@...> wrote: > > > On Fri, Jul 11, 2008 at 11:00:21AM -0500, Jeremy C. Reed wrote: > > > As a quick test, I did the following: > > > > I'm not sure if directly randomising the port is a good idea. > > I think it should at least be a random shuffle for the same reason > > that the TCP sequence numbers are not using a direct PRNG. > > I don't see the similarity. For sequence numbers, there's a > requirement in the RFC for a 4 microsecond counter; there's also > analysis concerning defense against old packets lying around the > network. Reusing the port number early increases both the chance of a collission with an existing port and the chance that you can still hit the query id case (for the special case of DNS). Joerg |
|
|
Re: randomize source portIf anyone wants to test timing, the attached patch also allows you to
toggle via sysctl. I tested by doing a loop of socket and connect and close 500000 times but didn't notice anything yet. (In fact, I can't detect more than one source port so probably done wrong. See second attachment.) I used time to time it with net.inet.ip.randomport as 0 and 1. Index: netinet/in.h =================================================================== RCS file: /cvsroot/src/sys/netinet/in.h,v retrieving revision 1.83 diff -u -r1.83 in.h --- netinet/in.h 25 Jan 2008 21:12:14 -0000 1.83 +++ netinet/in.h 11 Jul 2008 17:57:49 -0000 @@ -142,6 +142,7 @@ */ #define IPPORT_RESERVED 1024 +#define IPPORT_RANDOM 0 /* don't randomize by default */ #define IPPORT_ANONMIN 49152 #define IPPORT_ANONMAX 65535 #define IPPORT_RESERVEDMIN 600 @@ -451,7 +452,8 @@ #define IPCTL_RANDOMID 22 /* use random IP ids (if configured) */ #define IPCTL_LOOPBACKCKSUM 23 /* do IP checksum on loopback */ #define IPCTL_STATS 24 /* IP statistics */ -#define IPCTL_MAXID 25 +#define IPCTL_RANDOMPORT 25 /* enable randomized source port */ +#define IPCTL_MAXID 26 #define IPCTL_NAMES { \ { 0, 0 }, \ @@ -479,6 +481,7 @@ { "random_id", CTLTYPE_INT }, \ { "do_loopback_cksum", CTLTYPE_INT }, \ { "stats", CTLTYPE_STRUCT }, \ + { "randomport", CTLTYPE_INT }, \ } #endif /* _NETBSD_SOURCE */ Index: netinet/in_pcb.c =================================================================== RCS file: /cvsroot/src/sys/netinet/in_pcb.c,v retrieving revision 1.125 diff -u -r1.125 in_pcb.c --- netinet/in_pcb.c 5 May 2008 17:11:17 -0000 1.125 +++ netinet/in_pcb.c 11 Jul 2008 17:57:49 -0000 @@ -146,6 +146,7 @@ ((ntohl((faddr).s_addr) + ntohs(fport)) + \ (ntohl((laddr).s_addr) + ntohs(lport))) & (table)->inpt_connecthash] +int randomport = IPPORT_RANDOM; int anonportmin = IPPORT_ANONMIN; int anonportmax = IPPORT_ANONMAX; int lowportmin = IPPORT_RESERVEDMIN; @@ -332,6 +333,9 @@ mymax = swp; } + if (randomport != 0) + *lastport = mymax - (arc4random() % (mymax - mymin)); + lport = *lastport - 1; for (cnt = mymax - mymin + 1; cnt; cnt--, lport--) { if (lport < mymin || lport > mymax) Index: netinet/ip_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_input.c,v retrieving revision 1.272 diff -u -r1.272 ip_input.c --- netinet/ip_input.c 5 May 2008 17:11:17 -0000 1.272 +++ netinet/ip_input.c 11 Jul 2008 17:57:49 -0000 @@ -2412,6 +2412,13 @@ sysctl_net_inet_ip_stats, 0, NULL, 0, CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "randomport", + SYSCTL_DESCR("Enable source port randomization"), + NULL, 0, &randomport, 0, + CTL_NET, PF_INET, IPPROTO_IP, + IPCTL_RANDOMPORT, CTL_EOL); } void Index: netinet/ip_var.h =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_var.h,v retrieving revision 1.87 diff -u -r1.87 ip_var.h --- netinet/ip_var.h 12 Apr 2008 05:58:22 -0000 1.87 +++ netinet/ip_var.h 11 Jul 2008 17:57:49 -0000 @@ -183,6 +183,7 @@ extern int ipforwarding; /* ip forwarding */ extern int ip_mtudisc; /* mtu discovery */ extern int ip_mtudisc_timeout; /* seconds to timeout mtu discovery */ +extern int randomport; /* randomize source port */ extern int anonportmin; /* minimum ephemeral port */ extern int anonportmax; /* maximum ephemeral port */ extern int lowportmin; /* minimum reserved port */ #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <string.h> int s, t; struct sockaddr_in server; main () { for (t=0; t<500000; t++) { s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); memset((char *) &server, 0, sizeof(server)); server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_family = AF_INET; server.sin_port = htons(68); if (connect (s, (struct sockaddr *)&server, sizeof(server))) { perror ("connect"); } close(s); } printf("%d\n", t); } |
|
|
Re: randomize source portSteven M. Bellovin wrote:
> ... > How easy would it be to do a timing test? For example, assume a simple > program that just counted how many UDP ports it could bind to in ten > seconds? I expect some impact, but not a big one; arc4 is very cheap, > but measurement is always good. > Semi-related to this, I've been looking at this at work. On a Sun Ultra20, I think it was ~2,000,000/second. Compared with the libc random on Solaris, which was 10 or 100x that number. But really it isn't how many per second you can do but how much CPU it takes to do one and how much CPU you have left for other things. For example, with NAT using arc4random, it couldn't hope to create 2,000,000 sessions per second. I think you'd be lucky to be doing 200,000 bind()'s per second to new ports :) > More seriously -- when at boot time does urandom have enough entropy to > seed the PRNG? I've had problems on some server systems with things > like that. > arc4random, as per libkern, reseeds itself either every 5 minutes or 16k calls. If arc4random is too CPU intensive, is it worth using libc's rand and seeding that automatically in the kernel as we do with arc4random? Darren |
|
|
Re: randomize source portOn Thu, Jul 24, 2008 at 03:29:04AM -0700, Darren Reed wrote:
> If arc4random is too CPU intensive, is it worth using libc's rand and > seeding that automatically in the kernel as we do with arc4random? It would be better to use the Mersenne twister or something like sober as prng in that case. Both are cryptographhically strong PRNGs and can be a lot faster than arc4random. Joerg |
| Free Forum Powered by Nabble | Forum Help |