dos: Add the DoSRefuseSingleHopClientRendezvous option

This option refuses any ESTABLISH_RENDEZVOUS cell arriving from a client
connection. Its default value is "auto" for which we can turn it on or off
with a consensus parameter. Default value is 0.

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
David Goulet 2018-01-25 16:32:28 -05:00
parent acf7ea77d8
commit 36a0ae151f
3 changed files with 46 additions and 0 deletions

View File

@ -14,6 +14,7 @@
#include "geoip.h"
#include "main.h"
#include "networkstatus.h"
#include "router.h"
#include "dos.h"
@ -60,6 +61,9 @@ static uint64_t conn_num_addr_rejected;
* General interface of the denial of service mitigation subsystem.
*/
/* Keep stats for the heartbeat. */
static uint64_t num_single_hop_client_refused;
/* Return true iff the circuit creation mitigation is enabled. We look at the
* consensus for this else a default value is returned. */
MOCK_IMPL(STATIC unsigned int,
@ -524,6 +528,33 @@ dos_conn_addr_get_defense_type(const tor_addr_t *addr)
/* General API */
/* Note down that we've just refused a single hop client. This increments a
* counter later used for the heartbeat. */
void
dos_note_refuse_single_hop_client(void)
{
num_single_hop_client_refused++;
}
/* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
* be refused. */
int
dos_should_refuse_single_hop_client(void)
{
/* If we aren't a public relay, this shouldn't apply to anything. */
if (!public_server_mode(get_options())) {
return 0;
}
if (get_options()->DoSRefuseSingleHopClientRendezvous != -1) {
return get_options()->DoSRefuseSingleHopClientRendezvous;
}
return (int) networkstatus_get_param(NULL,
"DoSRefuseSingleHopClientRendezvous",
0 /* default */, 0, 1);
}
/* Called when a new client connection has been established on the given
* address. */
void

View File

@ -51,6 +51,9 @@ int dos_enabled(void);
void dos_new_client_conn(or_connection_t *or_conn);
void dos_close_client_conn(const or_connection_t *or_conn);
int dos_should_refuse_single_hop_client(void);
void dos_note_refuse_single_hop_client(void);
/*
* Circuit creation DoS mitigation subsystemn interface.
*/

View File

@ -8,9 +8,11 @@
**/
#include "or.h"
#include "channel.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "config.h"
#include "dos.h"
#include "relay.h"
#include "rendmid.h"
#include "rephist.h"
@ -246,6 +248,16 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
goto err;
}
/* Check if we are configured to accept established rendezvous cells from
* client or in other words tor2web clients. */
if (channel_is_client(circ->p_chan) &&
dos_should_refuse_single_hop_client()) {
/* Note it down for the heartbeat log purposes. */
dos_note_refuse_single_hop_client();
/* Silent drop so the client has to time out before moving on. */
return 0;
}
if (circ->base_.n_chan) {
log_warn(LD_PROTOCOL,
"Tried to establish rendezvous on non-edge circuit");