Use observed instead of declared uptime for HSDir

It is important to verify the uptime claim of a relay instead of just
trusting it, otherwise it becomes too easy to blackhole a specific
hidden service. rephist already has data available that we can use here.

Bugfix on 0.2.0.10-alpha.
This commit is contained in:
Sebastian Hahn 2011-03-09 11:34:04 +01:00
parent 48c4d53281
commit f7a3cdc8f2
4 changed files with 40 additions and 1 deletions

7
changes/hsdir_assignment Normal file
View File

@ -0,0 +1,7 @@
o Security fixes:
- Directory authorities now use data collected from rephist when
choosing whether to assign the HSDir flag to relays, instead of
trusting the uptime value the relay reports in its descriptor.
This helps prevent an attack where relatively few malaicious
nodes can blackhole any given hidden service. Bugfix on
0.2.0.10-alpha; fixes bug 2709.

View File

@ -43,6 +43,8 @@
extern time_t time_of_process_start; /* from main.c */
extern long stats_n_seconds_working; /* from main.c */
/** Do we need to regenerate the v1 directory when someone asks for it? */
static time_t the_directory_is_dirty = 1;
/** Do we need to regenerate the v1 runningrouters document when somebody
@ -1775,7 +1777,22 @@ dirserv_thinks_router_is_unreliable(time_t now,
static int
dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
{
long uptime = real_uptime(router, now);
long uptime;
/* If we haven't been running for at least
* get_options()->MinUptimeHidServDirectoryV2 seconds, we can't
* have accurate data telling us a relay has been up for at least
* that long. We also want to allow a bit of slack: Reachability
* tests aren't instant. If we haven't been running long enough,
* trust the relay. */
if (stats_n_seconds_working >
get_options()->MinUptimeHidServDirectoryV2 * 1.1)
uptime = MIN(rep_hist_get_uptime(router->cache_info.identity_digest, now),
real_uptime(router, now));
else
uptime = real_uptime(router, now);
/* XXX We shouldn't need to check dir_port, but we do because of
* bug 1693. In the future, once relays set wants_to_be_hs_dir

View File

@ -528,6 +528,20 @@ get_weighted_fractional_uptime(or_history_t *hist, time_t when)
return ((double) up) / total;
}
/** Return how long the router whose identity digest is <b>id</b> has
* been reachable. Return 0 if the router is unknown or currently deemed
* unreachable. */
long
rep_hist_get_uptime(const char *id, time_t when)
{
or_history_t *hist = get_or_history(id);
if (!hist)
return 0;
if (!hist->start_of_run)
return 0;
return when - hist->start_of_run;
}
/** Return an estimated MTBF for the router whose identity digest is
* <b>id</b>. Return 0 if the router is unknown. */
double

View File

@ -40,6 +40,7 @@ int rep_hist_record_mtbf_data(time_t now, int missing_means_down);
int rep_hist_load_mtbf_data(time_t now);
time_t rep_hist_downrate_old_runs(time_t now);
long rep_hist_get_uptime(const char *id, time_t when);
double rep_hist_get_stability(const char *id, time_t when);
double rep_hist_get_weighted_fractional_uptime(const char *id, time_t when);
long rep_hist_get_weighted_time_known(const char *id, time_t when);