[Xorp-hackers] OSPF auth...

Pavlin Radoslavov pavlin@icir.org
Fri, 17 Mar 2006 03:40:06 -0800


> Pavlin Radoslavov wrote:
> > This is different from the mechanism suggested by RFC 2082
> > (Section 4.3).
> 
> Which is from 1997. And which is different from recommendations in RFC2328 
> (appendix D) from 1998.
> 
> At first - time is passed since these times. Many points valid in these 
> days are void nowadays. Take RFC2328 appendix B - Architectural 
> Constants. They were meant to be really constants in '98, but I don't 
> know any commercial OSPF implementation which have first three constants 
> set to values defined there. They aren't even constants any more, but 
> adaptive values.
> 
> And even if something is described in (recent) RFC, it doesn't mean that 
> it is useful. Many times writers of standards put something into RFC's 
> which turned to be void issue in practise or too complicate to implement 
> or ... "Should" and "should not" are interpreted as "you can ignore this" 
> anyway by implementers. No joking, btw, these are words from Juniper 
> engineer.
> 
> Back to OSPF auth issues. Just start and end times valid for both 
> generating and accepting are not suitable for OSPF. Think of hello timers 
> set to 1s or even less (there are some implementations with thing called 
> "fast timers"). Even slight difference in clocks would bring adjacencies 
> down.
> 
> As far as I can see there is mostly two different ways the OSPF key switch 
> mechanism is implemented in nowadays implementations (there are also 
> implementations which allow only one key configured at time, but it 
> shouldn't be option for Xorp).
> 
> IOS way: no any times associated with keys, if multiple keys are 
> configured, multiple copies of every packet are sent over the interface - 
> one with each configured keys.
> 
> Method is very simple, works well, but of course there is overhead in the 
> moment of switch. With thousands of external prefixes it can be quite 
> heavy traffic.
> 
> Junos way: one key active for sending OSPF packets, one timestamp can be 
> configured per key - start generate time. Rules for choosing active key 
> are simple: active is the key with most recent start-time in the past or 
> if there isn't such key, then key with greatest ID without start-time. As 
> you can see it's quite close to method described in D.3 RFC2328, except 
> that only KeyStartGenerate is implemented. Accept time is always 
> infinite.
> 
> In this way configuration and rules you should take into account are still 
> kept quite simple (although it is more complicated than IOS way), but 
> traffic overhead is avoided.
> 
> These are exactly the cases where implementers implemented minimal set of 
> features required in practise without cluttering CLI with useless options 
> which would make only shooting into foot easier. For Cisco engineers 
> traffic overhead was acceptable, for Junos engineers it wasn't.

Let me describe what we have implemented so far and what we are
planning to add so you can see the tradeoffs we have chosen.

* RIP MD5
  There is optional start time and optional end time per key.
  If start time is missing from the configuration, it means "now";
  if end time is missing from the configuration, it means "forever".
  Only while a key is valid (i.e., within its start-end time
  period), a packet that matches that key is accepted.
  Also, if a key is valid, RIP transmits a copy of the packet with
  that authentication key.
  This means that RIP may transmit each packet more than once during
  key switchover: one copy per valid key.
  Opbiiously, it increases the control traffic during the
  switchover, but as you say it is relatively simple and robust
  solution.
  Though, the major reason we have chosen this solution is because
  it is within the lines of RFC 2082 "RIP-2 MD5 Authentication"
  Section 4.3.
  There are few things we need to fix in the current implementation,
  but the basic mechanism will remain same.

  Interestingly, in Juniper you cannot configure the RIP MD5 key ID.
  E.g., see Juniper's "Routing Protocols Configuration Guide"
  (Release 7.5) document, page 417, and the following email:

  http://www.atm.tut.fi/list-archive/juniper-nsp/msg03544.html

* OSPF MD5
  Indeed, RFC 2328 Section D describes a mechanism where there are
  four time constants associated with a key: KeyStartAccept,
  KeyStartGenerate, KeyStopGenerate, KeyStopAccept.
  And, yes, currently in XORP we have
  KeyStartAccept=KeyStartGenerate and KeyStopGenerate=KeyStopAccept.
  Furthermore, unlike the RIP MD5 implementation, we don't send
  multiple OSPF packets (one per each valid). Instead, we send a
  single packet (for one of the valid keys).
  As it is, we understand that this solution won't work when the
  clocks are not synchronized. And we didn't want to send multiple
  packets (one per key) as we do for RIP so due to time constraints
  we decided to come back to it and improve it later (after the 1.2
  release is out).

  The Cisco solution is not really acceptable for us, not only
  because of the extra traffic but also because it doesn't follow
  RFC 2328.
  The Juniper solution is admirable, because they conform to RFC
  2328 and at the same time have a nice solution to deal with clock
  differences: KeyStartGenerate=NOW, and
  KeyStopGenerate=KeyStopAccept=INFINITY.

  The downside of the Juniper solution is that you can't timeout the
  keys, but you have to remember to delete them when not needed
  anymore. Indeed, in your scenario of updating the keys for all
  your routers this is not an issue because you are closely
  monitoring everything.
  However, in other scenarios it is preferable to have expiration
  time for the keys. E.g., think about a scenario when you want to
  create a temporary time window (e.g., for testing purpose) for
  someone when they are allowed to be a part of your OSPF network,
  and after that you want to automatically revoke the MD5 key used
  for the experiment.

  To solve the clock differences problem, we need to make sure that
  KeyStartAccept < KeyStartGenerate and KeyStopGenerate < KeyStopAccept 
  We don't want to make all four time values configurable by the
  user, because this will make the configuration process too
  complicated.

  To solve the KeyStartAccess < KeyStartGenerate requirement we
  could use the Juniper solution by assuming that KeyStartAccept=NOW;
  however, this won't solve the KeyStopGenerate < KeyStopAccept
  requirement.

  Instead, we plan to use a new configurable time variable, say
  TimeSlack that is used to calculate KeyStartAccept and
  KeyStopAccept:

  KeyStartAccept = KeyStartGenerate - TimeSlack
  KeyStopAccept  = KeyStopGenerate + TimeSlack

  The TimeSlack variable will have a default value (say, 1800 secs),
  and will be configurable, but typically the user won't need to do
  anything about it. By doing so we:

  - Provide the additional functionality of having start-time and/or
    end-time.
  - Have a (configurable) solution for the clock syncronization
    problem.
  - Avoid the duplicated traffic.
  - Keep the MD5 key configuration relatively simple.

If folks have other suggestions/recommendations, now is the time to
speak before the above mechanism is implemented.

Pavlin