add configuration and network parameters for stream dos mitigation

This commit is contained in:
trinity-1686a 2023-09-09 12:28:33 +02:00 committed by David Goulet
parent cc31724f40
commit 379fb329d9
3 changed files with 126 additions and 0 deletions

View File

@ -78,6 +78,24 @@ static uint64_t conn_num_addr_connect_rejected;
* circ_max_cell_queue_size_out limit before being marked. */
static uint32_t dos_num_circ_max_outq;
/*
* Stream denial of service mitigation.
*
* Namespace used for this mitigation framework is "dos_stream_".
*/
/* Is the connection DoS mitigation enabled? */
static unsigned int dos_stream_enabled = 0;
/* Consensus parameters. They can be changed when a new consensus arrives.
* They are initialized with the hardcoded default values. */
static dos_stream_defense_type_t dos_stream_defense_type;
static uint32_t dos_stream_rate = DOS_STREAM_RATE_DEFAULT;
static uint32_t dos_stream_burst = DOS_STREAM_BURST_DEFAULT;
/* Keep some stats for the heartbeat so we can report out. */
static uint64_t stream_num_rejected;
/*
* General interface of the denial of service mitigation subsystem.
*/
@ -258,6 +276,58 @@ get_param_conn_connect_defense_time_period(const networkstatus_t *ns)
INT32_MAX);
}
/* Return true iff the stream creation mitigation is enabled. We look at the
* consensus for this else a default value is returned. */
MOCK_IMPL(STATIC unsigned int,
get_param_stream_enabled, (const networkstatus_t *ns))
{
if (dos_get_options()->DoSStreamCreationEnabled != -1) {
return dos_get_options()->DoSStreamCreationEnabled;
}
return !!networkstatus_get_param(ns, "DoSStreamCreationEnabled",
DOS_STREAM_ENABLED_DEFAULT, 0, 1);
}
/* Return the parameter for the time rate that is how many stream per circuit
* over this time span. */
static uint32_t
get_param_stream_rate(const networkstatus_t *ns)
{
/* This is in seconds. */
if (dos_get_options()->DoSStreamCreationRate) {
return dos_get_options()->DoSStreamCreationRate;
}
return networkstatus_get_param(ns, "DoSStreamCreationRate",
DOS_STREAM_RATE_DEFAULT,
1, INT32_MAX);
}
/* Return the parameter for the maximum circuit count for the circuit time
* rate. */
static uint32_t
get_param_stream_burst(const networkstatus_t *ns)
{
if (dos_get_options()->DoSStreamCreationBurst) {
return dos_get_options()->DoSStreamCreationBurst;
}
return networkstatus_get_param(ns, "DoSStreamCreationBurst",
DOS_STREAM_BURST_DEFAULT,
1, INT32_MAX);
}
/* Return the consensus parameter of the circuit creation defense type. */
static uint32_t
get_param_stream_defense_type(const networkstatus_t *ns)
{
if (dos_get_options()->DoSStreamCreationDefenseType) {
return dos_get_options()->DoSStreamCreationDefenseType;
}
return networkstatus_get_param(ns, "DoSStreamCreationDefenseType",
DOS_STREAM_DEFENSE_TYPE_DEFAULT,
DOS_STREAM_DEFENSE_NONE, DOS_STREAM_DEFENSE_MAX);
}
/* Set circuit creation parameters located in the consensus or their default
* if none are present. Called at initialization or when the consensus
* changes. */
@ -283,6 +353,12 @@ set_dos_parameters(const networkstatus_t *ns)
/* Circuit. */
dos_num_circ_max_outq = get_param_dos_num_circ_max_outq(ns);
/* Stream. */
dos_stream_enabled = get_param_stream_enabled(ns);
dos_stream_defense_type = get_param_stream_rate(ns);
dos_stream_rate = get_param_stream_burst(ns);
dos_stream_burst = get_param_stream_defense_type(ns);
}
/* Free everything for the circuit creation DoS mitigation subsystem. */
@ -945,6 +1021,14 @@ dos_log_heartbeat(void)
"[DoSRefuseSingleHopClientRendezvous disabled]");
}
if (dos_stream_enabled) {
smartlist_add_asprintf(elems,
"%" PRIu64 " stream rejected",
stream_num_rejected);
} else {
smartlist_add_asprintf(elems, "[DoSStreamCreationEnabled disabled]");
}
/* HS DoS stats. */
smartlist_add_asprintf(elems,
"%" PRIu64 " INTRODUCE2 rejected",

View File

@ -159,6 +159,33 @@ typedef enum dos_conn_defense_type_t {
dos_conn_defense_type_t dos_conn_addr_get_defense_type(const tor_addr_t *addr);
/*
* Stream creation DoS mitigation subsystem interface.
*/
/* DoSStreamCreationEnabled default. Disabled by deault. */
#define DOS_STREAM_ENABLED_DEFAULT 0
/* DoSStreamCreationDefenseType maps to the dos_stream_defense_type_t enum */
#define DOS_STREAM_DEFENSE_TYPE_DEFAULT DOS_STREAM_DEFENSE_REFUSE_STREAM
/* DosStreamCreationRate is 100 per seconds. */
#define DOS_STREAM_RATE_DEFAULT 100
/* DosStreamCreationBurst default. */
#define DOS_STREAM_BURST_DEFAULT 300
/* Type of defense that we can use for the stream creation DoS mitigation. */
typedef enum dos_stream_defense_type_t {
/* No defense used. */
DOS_STREAM_DEFENSE_NONE = 1,
/* Reject the stream */
DOS_STREAM_DEFENSE_REFUSE_STREAM = 2,
/* Close the circuit */
DOS_STREAM_DEFENSE_CLOSE_CIRCUIT = 3,
/* Maimum value that can be used. Useful for the boundaries of the
* consensus parameter. */
DOS_STREAM_DEFENSE_MAX = 3,
} dos_stream_defense_type_t;
#ifdef DOS_PRIVATE
STATIC uint32_t get_param_conn_max_concurrent_count(
@ -176,6 +203,8 @@ MOCK_DECL(STATIC unsigned int, get_param_cc_enabled,
(const networkstatus_t *ns));
MOCK_DECL(STATIC unsigned int, get_param_conn_enabled,
(const networkstatus_t *ns));
MOCK_DECL(STATIC unsigned int, get_param_stream_enabled,
(const networkstatus_t *ns));
#endif /* defined(DOS_PRIVATE) */

View File

@ -50,6 +50,19 @@ CONF_VAR(DoSConnectionConnectBurst, POSINT, 0, "0")
/** Allowed rate of client connection allowed per address. */
CONF_VAR(DoSConnectionConnectRate, POSINT, 0, "0")
/** Autobool: Is the stream creation DoS mitigation subsystem enabled? */
CONF_VAR(DoSStreamCreationEnabled, AUTOBOOL, 0, "auto")
/** Stream rate used to refill the token bucket. */
CONF_VAR(DoSStreamCreationRate, POSINT, 0, "0")
/** Maximum allowed burst of stream. */
CONF_VAR(DoSStreamCreationBurst, POSINT, 0, "0")
/** When an circuit is detected as malicious, what defense should be used
* against it. See the dos_stream_defense_type_t enum. */
CONF_VAR(DoSStreamCreationDefenseType, INT, 0, "0")
/** For how much time (in seconds) the connection connect rate defense is
* applicable for a malicious address. A random time delta is added to the
* defense time of an address which will be between 1 second and half of this