at present, there is no limit to the number of prefixes (and thus, routes)
that a IPv6 autohost will accept via router advertisements.
If an attacker floods the net with random RA announcements, at several
thousand (for my laptop: 5000 and a bit) the machine slows down to not
even updating time any longer. As soon as the flood stops, at least in the
case I tested, the machine fully recovered (apart from very unseemly
ifconfig output, and ifconfig taking noteable time to complete).
Daemons may not be coping with the number of addresses gracefully, too.
Limiting just the number of routes processed already fixes the slowdown,
but not the issues network programs may run into.
In order to deal with this, I propose to set a limit on the number of
prefixes and routes an autohost will accept. I name routes separately
since RFC4191 provides a mechanism for sending routes additionally to
prefixes; we do not yet support this but may do so in the future.
A proposed patch is at http://www.netbsd.org/~spz/rtadv-limit.diff
Comments? Improvements?
regards,
spz
--
s...@serpens.de (S.P.Zeidler)
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-...@muc.de
While I only know enough to be dangerous, the problem is really unlikely
to be routes (i.e. things installed in the routing table) per se. 5000
was a relatively reasonable number of routes 20 years ago when machines
running this code were way, way slower than they are now. I commonly test
the kernel routing table with a 1 million prefix dump obtained from someone's
core router.
I think instead that the problem is with IPv6-specific code like this:
struct nd_prefix *
nd6_prefix_lookup(struct nd_prefixctl *key)
{
struct nd_prefix *search;
LIST_FOREACH(search, &nd_prefix, ndpr_entry) {
if (key->ndpr_ifp == search->ndpr_ifp &&
key->ndpr_plen == search->ndpr_plen &&
in6_are_prefix_equal(&key->ndpr_prefix.sin6_addr,
&search->ndpr_prefix.sin6_addr, key->ndpr_plen)) {
break;
}
}
return (search);
}
A linear list like that is appropriate when there is normally just
one or two of something but where, only in some extreme corner case,
there might be a dozen or two manually configured, like IPv4 interface
addresses on a single interface. What this is doing, however, is a
full-blown automatic routing protocol, and the only reason to expect
there should only be a few of those is if you don't expect anyone
to actually use IPv6 for anything serious. This should be using a data
structure with better scaling properties.
That's not to say that having a configurable limit isn't reasonable (in
fact this protocol is complicated enough that it should probably be done
user space so it can have full-blown policy configuration should that be
needed; it usually is for other routing protocols), it is just that
doing it to fix this problem is just covering up the problem.
Dennis Ferguson
As I see it the original problem (a host accepting any random prefixes from
spoofed RAs) is not only the slow down; it's also that you end up with
an interface with a very large number of IPv6 addresses. This is not
only a performance issue, but also a connectivity DoS. A configurable
limit on this will restrict the effect of the DoS, and ease the job of
the human which will have to cleanup the mess ...
--
Manuel Bouyer <bou...@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--
I think it would be good to add a stat that counts RAs/prefixes
(something) that are rejected due to the count. Whenever I have
trouble I do "netstat -s" befoer and after trying something and diff
them, to find the counter that I didn't expect to change but does.
If this code ever gets in a bad state as it is we'll get silent failure
to accept RAs.
good point. either that, or a kernel printf() with a rate-limit.
--
Manuel Bouyer <bou...@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--
--
Thus wrote Dennis Ferguson (dennis.c...@gmail.com):
> On 11 May 2011, at 16:19 , S.P.Zeidler wrote:
> > at present, there is no limit to the number of prefixes (and thus, routes)
> > that a IPv6 autohost will accept via router advertisements.
> I think instead that the problem is with IPv6-specific code like this:
>
> struct nd_prefix *
> nd6_prefix_lookup(struct nd_prefixctl *key)
> {
[...]
> }
>
> A linear list like that is appropriate when there is normally just
> one or two of something but where, only in some extreme corner case,
> there might be a dozen or two manually configured, like IPv4 interface
> addresses on a single interface.
Right. I'm not expecting more than one or two prefixes being legally on one
LAN at the same time, take two interfaces, maybe three. I picked 42 as
"larger than most people will ever need to change".
> What this is doing, however, is a
> full-blown automatic routing protocol, and the only reason to expect
> there should only be a few of those is if you don't expect anyone
> to actually use IPv6 for anything serious.
It's SLAAC, the IPv6 moral equivalent of the "give me an IP address and a
default router" DHCP in IPv4. It's not supposed to be an IGP.
I would also add a sysctl to print the current numroutes.
christos