diff options
author | David Goulet <dgoulet@torproject.org> | 2022-08-04 10:03:19 -0400 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2022-08-09 11:01:12 -0400 |
commit | 8bf1a86ae1f3f71fa4b8b13f6d8eef5ad5eff8ca (patch) | |
tree | 75cafa4f6ce9f1449353d5098286a97a2a381cf3 | |
parent | 681c15a32d7d484ba90a32ab4b29b85447e7430c (diff) | |
download | tor-8bf1a86ae1f3f71fa4b8b13f6d8eef5ad5eff8ca.tar.gz tor-8bf1a86ae1f3f71fa4b8b13f6d8eef5ad5eff8ca.zip |
dirauth: Make voting flag threshold tunable via torrc
Remove UPTIME_TO_GUARANTEE_STABLE, MTBF_TO_GUARANTEE_STABLE,
TIME_KNOWN_TO_GUARANTEE_FAMILIAR WFU_TO_GUARANTEE_GUARD and replace each
of them with a tunnable torrc option.
Related to #40652
Signed-off-by: David Goulet <dgoulet@torproject.org>
-rw-r--r-- | changes/ticket40652 | 13 | ||||
-rw-r--r-- | doc/man/tor.1.txt | 21 | ||||
-rw-r--r-- | src/feature/dirauth/dirauth_config.c | 5 | ||||
-rw-r--r-- | src/feature/dirauth/dirauth_options.inc | 22 | ||||
-rw-r--r-- | src/feature/dirauth/voteflags.c | 39 |
5 files changed, 69 insertions, 31 deletions
diff --git a/changes/ticket40652 b/changes/ticket40652 index 2b9f2ee1cb..ff9f4d0591 100644 --- a/changes/ticket40652 +++ b/changes/ticket40652 @@ -1,5 +1,10 @@ o Minor features (dirauth): - - Add an AuthDirVoteGuard torrc option that can allow authorities to assign - the Guard flag to the given fingerprints/country code/IPs. This is a - needed feature mostly for defense purposes in case a DoS hits the network - and relay start losing the Guard flags too fast. Closes ticket 40652. + - Add an AuthDirVoteGuard torrc option that can allow authorities to + assign the Guard flag to the given fingerprints/country code/IPs. This + is a needed feature mostly for defense purposes in case a DoS hits the + network and relay start losing the Guard flags too fast. + - Make UPTIME_TO_GUARANTEE_STABLE, MTBF_TO_GUARANTEE_STABLE, + TIME_KNOWN_TO_GUARANTEE_FAMILIAR WFU_TO_GUARANTEE_GUARD tunable from + torrc. + - Add a torrc option to control the Guard flag bandwidth threshold + percentile. Closes ticket 40652. diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt index ba7cdbabc8..641d2d597e 100644 --- a/doc/man/tor.1.txt +++ b/doc/man/tor.1.txt @@ -3234,6 +3234,27 @@ on the public Tor network. nodes to vote Guard for regardless of their uptime and bandwidth. See <<ExcludeNodes,ExcludeNodes>> for more information on how to specify nodes. +[[AuthDirVoteGuardBwThresholdFraction]] **AuthDirVoteGuardBwThresholdFraction** __FRACTION__:: + The Guard flag bandwidth performance threshold fraction that is the + fraction representing who gets the Guard flag out of all measured + bandwidth. (Default: 0.75) + +[[AuthDirVoteGuardGuaranteeTimeKnown]] **AuthDirVoteGuardGuaranteeTimeKnown** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: + A relay with at least this much weighted time known can be considered + familiar enough to be a guard. (Default: 8 days) + +[[AuthDirVoteGuardGuaranteeWFU]] **AuthDirVoteGuardGuaranteeWFU** __FRACTION__:: + A level of weighted fractional uptime (WFU) is that is sufficient to be a + Guard. (Default: 0.98) + +[[AuthDirVoteStableGuaranteeMinUptime]] **AuthDirVoteStableGuaranteeMinUptime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: + If a relay's uptime is at least this value, then it is always considered + stable, regardless of the rest of the network. (Default: 30 days) + +[[AuthDirVoteStableGuaranteeMTBF]] **AuthDirVoteStableGuaranteeMTBF** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: + If a relay's mean time between failures (MTBF) is least this value, then + it will always be considered stable. (Default: 5 days) + [[BridgePassword]] **BridgePassword** __Password__:: If set, contains an HTTP authenticator that tells a bridge authority to serve all requested bridge information. Used by the (only partially diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c index 53c9f9f781..f98513ef75 100644 --- a/src/feature/dirauth/dirauth_config.c +++ b/src/feature/dirauth/dirauth_config.c @@ -434,6 +434,11 @@ dirauth_options_validate(const void *arg, char **msg) "Recommended*Versions."); } + if (options->AuthDirVoteGuardBwThresholdFraction > 1.0 || + options->AuthDirVoteGuardBwThresholdFraction < 0.0) { + REJECT("Guard bandwdith threshold fraction is invalid."); + } + char *t; /* Call these functions to produce warnings only. */ t = format_recommended_version_list(options->RecommendedClientVersions, 1); diff --git a/src/feature/dirauth/dirauth_options.inc b/src/feature/dirauth/dirauth_options.inc index 146dc7254c..7ee0201e1a 100644 --- a/src/feature/dirauth/dirauth_options.inc +++ b/src/feature/dirauth/dirauth_options.inc @@ -79,6 +79,28 @@ CONF_VAR(RecommendedServerVersions, LINELIST, 0, NULL) /** Relays which should be voted Guard regardless of uptime and bandwidth. */ CONF_VAR(AuthDirVoteGuard, ROUTERSET, 0, NULL) +/** If a relay's uptime is at least this value, then it is always considered + * stable, regardless of the rest of the network. This way we resist attacks + * where an attacker doubles the size of the network using allegedly + * high-uptime nodes, displacing all the current guards. */ +CONF_VAR(AuthDirVoteStableGuaranteeMinUptime, INTERVAL, 0, "30 days") + +/** If a relay's MTBF is at least this value, then it is always stable. See + * above. */ +CONF_VAR(AuthDirVoteStableGuaranteeMTBF, INTERVAL, 0, "5 days") + +/** A relay with at least this much weighted time known can be considered + * familiar enough to be a guard. */ +CONF_VAR(AuthDirVoteGuardGuaranteeTimeKnown, INTERVAL, 0, "8 days") + +/** A relay with sufficient WFU is around enough to be a guard. */ +CONF_VAR(AuthDirVoteGuardGuaranteeWFU, DOUBLE, 0, "0.98") + +/** The Guard flag bandwidth performance threshold fraction that is the + * fraction representing who gets the Guard flag out of all measured + * bandwidth. */ +CONF_VAR(AuthDirVoteGuardBwThresholdFraction, DOUBLE, 0, "0.75") + /** If an authority has been around for less than this amount of time, it * does not believe its reachability information is accurate. Only * altered on testing networks. */ diff --git a/src/feature/dirauth/voteflags.c b/src/feature/dirauth/voteflags.c index 52b84a9d89..71ee03e265 100644 --- a/src/feature/dirauth/voteflags.c +++ b/src/feature/dirauth/voteflags.c @@ -36,24 +36,6 @@ #include "lib/container/order.h" -/** If a router's uptime is at least this value, then it is always - * considered stable, regardless of the rest of the network. This - * way we resist attacks where an attacker doubles the size of the - * network using allegedly high-uptime nodes, displacing all the - * current guards. */ -#define UPTIME_TO_GUARANTEE_STABLE (3600*24*30) -/** If a router's MTBF is at least this value, then it is always stable. - * See above. (Corresponds to about 7 days for current decay rates.) */ -#define MTBF_TO_GUARANTEE_STABLE (60*60*24*5) -/** Similarly, every node with at least this much weighted time known can be - * considered familiar enough to be a guard. Corresponds to about 20 days for - * current decay rates. - */ -#define TIME_KNOWN_TO_GUARANTEE_FAMILIAR (8*24*60*60) -/** Similarly, every node with sufficient WFU is around enough to be a guard. - */ -#define WFU_TO_GUARANTEE_GUARD (0.98) - /* Thresholds for server performance: set by * dirserv_compute_performance_thresholds, and used by * generate_v2_networkstatus */ @@ -111,13 +93,13 @@ dirserv_thinks_router_is_unreliable(time_t now, */ long uptime = real_uptime(router, now); if ((unsigned)uptime < stable_uptime && - (unsigned)uptime < UPTIME_TO_GUARANTEE_STABLE) + uptime < dirauth_get_options()->AuthDirVoteStableGuaranteeMinUptime) return 1; } else { double mtbf = rep_hist_get_stability(router->cache_info.identity_digest, now); if (mtbf < stable_mtbf && - mtbf < MTBF_TO_GUARANTEE_STABLE) + mtbf < dirauth_get_options()->AuthDirVoteStableGuaranteeMTBF) return 1; } } @@ -325,13 +307,15 @@ dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil) /* (Now bandwidths is sorted.) */ if (fast_bandwidth_kb < RELAY_REQUIRED_MIN_BANDWIDTH/(2 * 1000)) fast_bandwidth_kb = bandwidths_kb[n_active/4]; + int nth = (int)(n_active * + dirauth_options->AuthDirVoteGuardBwThresholdFraction); guard_bandwidth_including_exits_kb = - third_quartile_uint32(bandwidths_kb, n_active); + find_nth_uint32(bandwidths_kb, n_active, nth); guard_tk = find_nth_long(tks, n_active, n_active/8); } - if (guard_tk > TIME_KNOWN_TO_GUARANTEE_FAMILIAR) - guard_tk = TIME_KNOWN_TO_GUARANTEE_FAMILIAR; + if (guard_tk > dirauth_options->AuthDirVoteGuardGuaranteeTimeKnown) + guard_tk = dirauth_options->AuthDirVoteGuardGuaranteeTimeKnown; { /* We can vote on a parameter for the minimum and maximum. */ @@ -379,15 +363,16 @@ dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil) } SMARTLIST_FOREACH_END(node); if (n_familiar) guard_wfu = median_double(wfus, n_familiar); - if (guard_wfu > WFU_TO_GUARANTEE_GUARD) - guard_wfu = WFU_TO_GUARANTEE_GUARD; + if (guard_wfu > dirauth_options->AuthDirVoteGuardGuaranteeWFU) + guard_wfu = dirauth_options->AuthDirVoteGuardGuaranteeWFU; enough_mtbf_info = rep_hist_have_measured_enough_stability(); if (n_active_nonexit) { + int nth = (int)(n_active_nonexit * + dirauth_options->AuthDirVoteGuardBwThresholdFraction); guard_bandwidth_excluding_exits_kb = - find_nth_uint32(bandwidths_excluding_exits_kb, - n_active_nonexit, n_active_nonexit*3/4); + find_nth_uint32(bandwidths_excluding_exits_kb, n_active_nonexit, nth); } log_info(LD_DIRSERV, |