hs-v3: Implement torrc DoS defenses options

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
David Goulet 2019-06-25 10:26:57 -04:00 committed by George Kadianakis
parent e4856d1bbf
commit 5419fd5d9f
5 changed files with 77 additions and 0 deletions

View File

@ -507,6 +507,11 @@ static config_var_t option_vars_[] = {
VAR("HiddenServiceMaxStreamsCloseCircuit",LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceNumIntroductionPoints", LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceExportCircuitID", LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceEnableIntroDoSDefense", LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceEnableIntroDoSRatePerSec",
LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceEnableIntroDoSBurstPerSec",
LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceStatistics", BOOL, HiddenServiceStatistics_option, "1"),
V(HidServAuth, LINELIST, NULL),
V(ClientOnionAuthDir, FILENAME, NULL),

View File

@ -218,6 +218,9 @@ config_has_invalid_options(const config_line_t *line_,
const char *opts_exclude_v2[] = {
"HiddenServiceExportCircuitID",
"HiddenServiceEnableIntroDoSDefense",
"HiddenServiceEnableIntroDoSRatePerSec",
"HiddenServiceEnableIntroDoSBurstPerSec",
NULL /* End marker. */
};
@ -276,6 +279,15 @@ config_validate_service(const hs_service_config_t *config)
goto invalid;
}
/* DoS validation values. */
if (config->has_dos_defense_enabled &&
(config->intro_dos_burst_per_sec < config->intro_dos_rate_per_sec)) {
log_warn(LD_CONFIG, "Hidden service DoS defenses burst (%" PRIu32 ") can "
"not be smaller than the rate value (%" PRIu32 ").",
config->intro_dos_burst_per_sec, config->intro_dos_rate_per_sec);
goto invalid;
}
/* Valid. */
return 0;
invalid:
@ -296,6 +308,8 @@ config_service_v3(const config_line_t *line_,
{
int have_num_ip = 0;
bool export_circuit_id = false; /* just to detect duplicate options */
bool dos_enabled = false, dos_rate_per_sec = false;
bool dos_burst_per_sec = false;
const char *dup_opt_seen = NULL;
const config_line_t *line;
@ -334,6 +348,48 @@ config_service_v3(const config_line_t *line_,
export_circuit_id = true;
continue;
}
if (!strcasecmp(line->key, "HiddenServiceEnableIntroDoSDefense")) {
config->has_dos_defense_enabled =
(unsigned int) helper_parse_uint64(line->key, line->value,
HS_CONFIG_V3_DOS_DEFENSE_DEFAULT,
1, &ok);
if (!ok || dos_enabled) {
if (dos_enabled) {
dup_opt_seen = line->key;
}
goto err;
}
dos_enabled = true;
continue;
}
if (!strcasecmp(line->key, "HiddenServiceEnableIntroDoSRatePerSec")) {
config->intro_dos_rate_per_sec =
(unsigned int) helper_parse_uint64(line->key, line->value,
HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MIN,
HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MAX, &ok);
if (!ok || dos_rate_per_sec) {
if (dos_rate_per_sec) {
dup_opt_seen = line->key;
}
goto err;
}
dos_rate_per_sec = true;
continue;
}
if (!strcasecmp(line->key, "HiddenServiceEnableIntroDoSBurstPerSec")) {
config->intro_dos_burst_per_sec =
(unsigned int) helper_parse_uint64(line->key, line->value,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MIN,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MAX, &ok);
if (!ok || dos_burst_per_sec) {
if (dos_burst_per_sec) {
dup_opt_seen = line->key;
}
goto err;
}
dos_burst_per_sec = true;
continue;
}
}
/* We do not load the key material for the service at this stage. This is

View File

@ -15,6 +15,14 @@
#define HS_CONFIG_MAX_STREAMS_PER_RDV_CIRCUIT 65535
/* Maximum number of intro points per version 3 services. */
#define HS_CONFIG_V3_MAX_INTRO_POINTS 20
/* Default value for the introduction DoS defenses. */
#define HS_CONFIG_V3_DOS_DEFENSE_DEFAULT 0
#define HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT 25
#define HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MIN 0
#define HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MAX INT32_MAX
#define HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT 200
#define HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MIN 0
#define HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MAX INT32_MAX
/* API */

View File

@ -242,6 +242,9 @@ set_service_default_config(hs_service_config_t *c,
c->is_single_onion = 0;
c->dir_group_readable = 0;
c->is_ephemeral = 0;
c->has_dos_defense_enabled = HS_CONFIG_V3_DOS_DEFENSE_DEFAULT;
c->intro_dos_rate_per_sec = HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT;
c->intro_dos_burst_per_sec = HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT;
}
/* From a service configuration object config, clear everything from it

View File

@ -241,6 +241,11 @@ typedef struct hs_service_config_t {
/* Does this service export the circuit ID of its clients? */
hs_circuit_id_protocol_t circuit_id_protocol;
/* DoS defenses. For the ESTABLISH_INTRO cell extension. */
unsigned int has_dos_defense_enabled : 1;
uint32_t intro_dos_rate_per_sec;
uint32_t intro_dos_burst_per_sec;
} hs_service_config_t;
/* Service state. */