Subject: Re: Outstanding queries vs. source port randomization entropy

From: Mark Andrews <[email-masked]>
Date: Mon, 01 Sep 2008 10:46:59 +1000

> 
> > On 2008-08-31 23:26, Mark Andrews wrote:
> > > Jefferson Ogata wrote [attribution restored]:
> > >>  The 
> > >> attack could be partly mitigated on nameservers that allow ~2^16 
> > >> outstanding requests if the victim nameserver can reuse randomly chosen,
>  
> > >> already open sockets for multiple successive requests once ~2^16 ports 
> > >> are bound.
> > >>
> > > 	You still need to randomly select ports and randomly select
> > > 	txid.  When you have a collision you just need to repick
> > > 	one and/or the other.   A port collision alone lets you use
> > > 	a existing socket.
> > 
> > I believe I considered that possibility in the above part of my comment. 
> > The question in that case remains: does any existing resolver that 
> > supports source port randomization actually do this?
> > 
> > > 	For queries to another server you just set SO_REUSEADDR
> > > 	when you have a port collision with a port you already have
> > > 	open as the existing one is in a connected state.  If it
> > > 	is a port that is not already in use you don't set SO_REUSEADDR
> > > 	so you detect collisions with other applications.
> > 
> > I don't see why you need SO_REUSEADDR. Why not simply leave the UDP port 
> > unconnected and use sendto in the first place?
> 
> 	Because you really want to have the kernel do the initial
> 	filtering of responses.  You don't want your recursive
> 	server seeing every stray UDP packet being sent to you.
> 	With the amount of malware out there that is trying to get
> 	in over UDP your recursive server will be getting lots of
> 	noise if you randomly choose such a port.  Connected sockets
> 	don't interfere with other uses of UDP (e.g. traceroute).
> 	You can't probe to see what ports are in use by the recursive
> 	server without making the server actually make queries to
> 	you.
> 
> 	Mark

	Additionally with sendto() you will tend to get locked onto
	a open set of ports as you need to wait for the next response
	whenever you re-use a port.  With connect() each transaction
	becomes almost completely independent of other transaction.

	Note all the probability analysis being done assume
	independent transactions.  If you have depenancies between
	transactions (i.e. re-use of a socket) then all the analyses
	needs to be redone to factor in that socket re-use.

	Even without doing such a analysis I can tell you that
	re-use makes the system weaker not stronger.

	Mark

> > -- 
> > Jefferson Ogata : Internetworker, Antibozo
> > 
> > --
> > to unsubscribe send a message to [email-masked] with
> > the word 'unsubscribe' in a single line as the message text body.
> > archive: <http://ops.ietf.org/lists/namedroppers/>
> -- 
> Mark Andrews, ISC
> 1 Seymour St., Dundas Valley, NSW 2117, Australia
> PHONE: +61 2 9871 4742                 INTERNET: [email-masked]
-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: [email-masked]

--
to unsubscribe send a message to [email-masked] with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://ops.ietf.org/lists/namedroppers/>

---

From: Jefferson Ogata <[email-masked]>
Date: Mon, 01 Sep 2008 01:02:58 +0000

> 	becomes almost completely independent of other transaction.

I don't follow; when you have ~2^16 distinct source ports bound, how can 
you get locked into a sub-optimal set of ports?

Your point about combining connected UDP sockets with SO_REUSEADDR in 
order to take advantage of kernel filtering and avoid impacting on other 
uses of UDP is well taken, but a drawback I see is that your file 
descriptor set has to continue to grow past 2^16 if you don't actually 
reuse existing sockets.

> 	re-use makes the system weaker not stronger.

I only speculate about reuse of source ports as mitigation against the 
complete loss of source port entropy once the number of free source 
ports becomes small. I.e. the source port would continue to be random 
regardless of the size of the pool of available source ports. I don't 
see how this makes the system weaker; what am I missing?

---

From: Mark Andrews <[email-masked]>
Date: Mon, 01 Sep 2008 11:44:59 +1000

> you get locked into a sub-optimal set of ports?

	Ususally you don't have 2^16 ports in use.
	
> descriptor set has to continue to grow past 2^16 if you don't actually 

	Yes.  There are tradeoffs everywhere in this space.
 
	Mark

---

From: Jefferson Ogata <[email-masked]>
Date: Mon, 01 Sep 2008 03:33:05 +0000

On 2008-09-01 01:44, Mark Andrews wrote:
> Jefferson Ogata wrote [attribution restored, again--dude, you should fix that]:

Well, yes, in which case, you are just using new ports as usual. Am I 
being very unclear?

Really, the optimal behavior would be to choose the source port for the 
next query based strictly on your entropy source, and not on 
availability at all. So once you pass 2^15 outstanding queries, you 
would be more likely to reuse a source port than not to, if you want to 
maintain unpredictability of source port numbers.

So it seems to me that any implementation that is not designed to reuse 
source ports, even at a very low rate when there are only a few 
outstanding queries, is not optimizing the entropy available in source 
port randomization.