Filename: 212-using-old-consensus.txt
Title: Increase Acceptable Consensus Age
Author: Mike Perry
Created: 01-10-2012
Status: Needs-Revision
Target: 0.2.4.x+

Overview

  This proposal aims to extend the duration that clients will accept
  old consensus material under conditions where the directory authorities
  are either down or fail to produce a valid consensus for an extended
  period of time.

Motivation

  Currently, if the directory authorities are down or fail to consense
  for 24 hours, the entire Tor network will cease to function. Worse,
  clients will enter into a state where they all need to re-bootstrap
  directly from the directory authorities, which will likely exacerbate
  any potential DoS condition that may have triggered the downtime in the
  first place.

  The Tor network has had such close calls before. In the past, we've
  been able to mobilize a majority of the directory authority operators
  within this 24 hour window, but that is only because we've been
  exceedingly lucky and the DoS conditions were accidental rather than
  deliberate.

  If a DoS attack was deliberately timed to coincide with a major US
  and European combined holiday such as Christmas Eve, New Years Eve, or
  Easter, it is very unlikely we would be able to muster the resources to
  diagnose and deploy a fix to the authorities in time to prevent network
  collapse.

Description

  Based on the need to survive multi-day holidays and long weekends
  balanced with the need to ensure clients can't be captured on an old
  consensus forever, I propose that the consensus liveness constants be
  set at 3 days rather than 24 hours.

  This requires updating two consensus defines in the source, and one
  descriptor freshness variable. The descriptor freshness should be
  set to a function of the consensus freshness.

  See Implementation Notes for further details.

Security Concerns: Using an Old Consensus

  Clients should not trust old consensus data without an attempt to
  download fresher data from a directory mirror.

  As far as I could tell, the code already does this. The minimum
  consensus age before we try to download new data is two hours.

  However, the ability to accept old consensus documents does introduce
  the ability of malicious directory mirrors to feed their favorite old
  consensus document to clients to alter their paths until they
  download a fresher consensus from elsewhere. Directory guards
  (Proposal 207) may exacerbate this ability.

  This proposal does not address such attacks, and seeks only a modest
  increase in the valid timespan as a compromise.

  Future consideration of these and other targeted-consensus attacks
  will be left to proposals related to ticket #7126[1]. Once those
  proposals are complete and implemented, raising the freshness limit
  beyond 3 days should be possible.

Implementation Notes

  There appear to be at least three constants in the code involved with
  using potentially expired consensus data. Two of them
  (REASONABLY_LIVE_TIME and NS_EXPIRY_SLOP) involve the consensus itself,
  and two (OLD_ROUTER_DESC_MAX_AGE and TOLERATE_MICRODESC_AGE) deal with
  descriptor liveness.

  Two additional constants ROUTER_MAX_AGE and ROUTER_MAX_AGE_TO_PUBLISH
  are only used when submitting descriptors for consensus voting.

  FORCE_REGENERATE_DESCRIPTOR_INTERVAL is the maximum age a router
  descriptor will get before a relay will re-publish. It is set to 18
  hours.

  OLD_ROUTER_DESC_MAX_AGE is set at 5 days. TOLERATE_MICRODESC_AGE
  is set at 7 days.

  The consensus timestamps are used in
  networkstatus_get_reasonably_live_consensus() and 
  networkstatus_set_current_consensus().

  OLD_ROUTER_DESC_MAX_AGE is checked in routerlist_remove_old_routers(), 
  router_add_to_routerlist(), and client_would_use_router().

  It is my opinion that we should combine REASONABLY_LIVE_TIME and
  NS_EXPIRY_SLOP into a single define, and make OLD_ROUTER_DESC_MAX_AGE a
  function of REASONABLY_LIVE_TIME and FORCE_REGENERATE_DESCRIPTOR_INTERVAL:

  #define REASONABLY_LIVE_TIME           (3*24*60*60)
  #define NS_EXPIRY_SLOP                 REASONABLY_LIVE_TIME
  #define OLD_ROUTER_DESC_MAX_AGE        \
          (REASONABLY_LIVE_TIME+FORCE_REGENERATE_DESCRIPTOR_INTERVAL)

  Based on my review of the above code paths, these changes should be all
  we need to enable clients to use older consensuses for longer while
  still attempting to fetch new ones.

1. https://trac.torproject.org/projects/tor/ticket/7126