What about IPv6? /64? /48?
For IPv4 /16 roughly means that each combination of "local registry" and "ISP allocation" is captured, while less than an ISP is considered non-unique. Some entities have /8's from legacy allocations mind you, the likes of IBM, MIT etc. so in theory filtering at /16 lets them get 256 nodes past the uniqueness filter.
For IPv6 even /48 is right out as the allocation RFCs encourage a /48 per customer; I've got a /56 for my home DSL connection. Getting multiple /48's isn't hard at all.
If you look at the
IPv6 allocations you see that the global unicast space is currently allocated out of 2::/3 and the registry level allocations happen at roughly the /16-/20 level. That would imply /28 is probably a reasonable uniqueness filter.
6to4 traffic is a special case as a 6to4 address embeds an IPv4 address following the 2002:/16 prefix. Thus the /16 rule for IPv4 implies you should filter at the /32 level. With
Teredo tunneling the Teredo server address follows a 2002:0000:/32 prefix, followed by some flag bits, a port number, and the IPv4 client address. However while in the general case a Teredo server does *not* actually carry the IPv6 traffic, I'm not sure that an attacker couldn't fake IPv4 connections,(1) so you're probably still stuck applying the /16 filter to the server's address. Thus filtering at 2002:/48 is reasonable, as is not having a special Teredo rule at all. (who knows if Teredo advertisement inbound router filters are maintained properly) Equally not having a special rule for 6to4 isn't bad, and just implies you're filtering the embedded IPv4 addresses at the /12 level with a /28 v6 filter.
The one good thing is 6to4 and Teredo relays are becoming fairly common, with
many ISPs running local relays, thus external attackers have a harder time capturing a lot of traffic by advertising an appropriate route. (remember, all this stuff assumes we trust our ISP)
Another issue is that since the IPv6 space is so plentiful an attacker could also make arrangements to borrow space from a registry on a temporary basis, or even borrow a whole registry-level prefix. Secondly an attacker could also try just advertising a whole prefix on the global routing table; the only thing stopping them is the often badly applied inbound route filtering done by ISPs. I'll bet you there are plenty who haven't gotten around to removing rules allowing 3ffe:/16 advertisements for instance.
It'd be interesting to try to capture as many IPv6 addresses on the network as it stands and get a sense of how they are distributed across the address space. For that matter, do the same thing for IPv4. For what it's worth I run my bitcoin node IPv6-only, and right now the peer list is fully unique at the /22 level, with all but two IPs unique at /20.
1) Teredo is complex... It separates the relay, the host that carries the traffic, from the server, the host that gets the client connected. The server only forwards IPv6 pings on behalf of the client. Each time the client wants to connect to a new IPv6 address it creates a ping to that address and tells the server to send that ping on it's behalf. This ping has the same source address as the client's IPv6 address. When the destination responds the response will end up at the nearest Teredo relay, either a router advertising the 2002:/32 prefix, or a non-advertising router in the upstream path of the destination. That router intercepts the packet and contacts the originating client directly at the embedded IPv4 address and port via UDP to get past most types of NAT. Due to the way the relays work in most cases you need to control an IPv4 address to be able to use a specific Teredo IPv6 address. However if the attacker also has control of a relay local to you they can intercept whole address spaces, and control of a relay is no harder than advertising 2002:/32; they don't have to be your ISP. On the other hand if you assume they don't have that control then the uniqueness filter becomes a
mask rather than a prefix, so you need a whole bunch of code if you didn't implement prefixes as bit masks.
My suggestion? Don't have a special Teredo rule to avoid all this complexity. Teredo clients aren't that common anyway.