mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-13 22:53:44 +01:00
Merge remote-tracking branch 'mbeth-private/ticket40821_mr'
This commit is contained in:
commit
e39fb0962f
@ -83,6 +83,7 @@
|
|||||||
#include "lib/time/compat_time.h"
|
#include "lib/time/compat_time.h"
|
||||||
|
|
||||||
#include "core/or/cell_queue_st.h"
|
#include "core/or/cell_queue_st.h"
|
||||||
|
#include "core/or/or_connection_st.h"
|
||||||
|
|
||||||
/* Global lists of channels */
|
/* Global lists of channels */
|
||||||
|
|
||||||
@ -1864,7 +1865,6 @@ channel_do_open_actions(channel_t *chan)
|
|||||||
{
|
{
|
||||||
tor_addr_t remote_addr;
|
tor_addr_t remote_addr;
|
||||||
int started_here;
|
int started_here;
|
||||||
time_t now = time(NULL);
|
|
||||||
int close_origin_circuits = 0;
|
int close_origin_circuits = 0;
|
||||||
|
|
||||||
tor_assert(chan);
|
tor_assert(chan);
|
||||||
@ -1875,23 +1875,26 @@ channel_do_open_actions(channel_t *chan)
|
|||||||
circuit_build_times_network_is_live(get_circuit_build_times_mutable());
|
circuit_build_times_network_is_live(get_circuit_build_times_mutable());
|
||||||
router_set_status(chan->identity_digest, 1);
|
router_set_status(chan->identity_digest, 1);
|
||||||
} else {
|
} else {
|
||||||
/* only report it to the geoip module if it's a client */
|
/* only report it to the geoip module if it's a client and it hasn't
|
||||||
|
* already been set up for tracking earlier. (Incoming TLS connections
|
||||||
|
* are tracked before the handshake.) */
|
||||||
if (channel_is_client(chan)) {
|
if (channel_is_client(chan)) {
|
||||||
if (channel_get_addr_if_possible(chan, &remote_addr)) {
|
if (channel_get_addr_if_possible(chan, &remote_addr)) {
|
||||||
char *transport_name = NULL;
|
|
||||||
channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
|
channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
|
||||||
if (chan->get_transport_name(chan, &transport_name) < 0)
|
if (!tlschan->conn->tracked_for_dos_mitigation) {
|
||||||
|
char *transport_name = NULL;
|
||||||
|
if (chan->get_transport_name(chan, &transport_name) < 0) {
|
||||||
transport_name = NULL;
|
transport_name = NULL;
|
||||||
|
}
|
||||||
geoip_note_client_seen(GEOIP_CLIENT_CONNECT,
|
geoip_note_client_seen(GEOIP_CLIENT_CONNECT,
|
||||||
&remote_addr, transport_name,
|
&remote_addr, transport_name,
|
||||||
now);
|
time(NULL));
|
||||||
/* Notify the DoS subsystem of a new client. */
|
|
||||||
if (tlschan && tlschan->conn) {
|
if (tlschan && tlschan->conn) {
|
||||||
dos_new_client_conn(tlschan->conn, transport_name);
|
dos_new_client_conn(tlschan->conn, transport_name);
|
||||||
}
|
}
|
||||||
tor_free(transport_name);
|
tor_free(transport_name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Otherwise the underlying transport can't tell us this, so skip it */
|
/* Otherwise the underlying transport can't tell us this, so skip it */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "core/or/circuitmux.h"
|
#include "core/or/circuitmux.h"
|
||||||
#include "core/or/circuitmux_ewma.h"
|
#include "core/or/circuitmux_ewma.h"
|
||||||
#include "core/or/command.h"
|
#include "core/or/command.h"
|
||||||
|
#include "core/or/dos.h"
|
||||||
#include "app/config/config.h"
|
#include "app/config/config.h"
|
||||||
#include "app/config/resolve_addr.h"
|
#include "app/config/resolve_addr.h"
|
||||||
#include "core/mainloop/connection.h"
|
#include "core/mainloop/connection.h"
|
||||||
@ -54,6 +55,7 @@
|
|||||||
#include "trunnel/link_handshake.h"
|
#include "trunnel/link_handshake.h"
|
||||||
#include "core/or/relay.h"
|
#include "core/or/relay.h"
|
||||||
#include "feature/stats/rephist.h"
|
#include "feature/stats/rephist.h"
|
||||||
|
#include "feature/stats/geoip_stats.h"
|
||||||
#include "feature/relay/router.h"
|
#include "feature/relay/router.h"
|
||||||
#include "feature/relay/routermode.h"
|
#include "feature/relay/routermode.h"
|
||||||
#include "feature/nodelist/dirlist.h"
|
#include "feature/nodelist/dirlist.h"
|
||||||
@ -358,6 +360,14 @@ channel_tls_handle_incoming(or_connection_t *orconn)
|
|||||||
/* Register it */
|
/* Register it */
|
||||||
channel_register(chan);
|
channel_register(chan);
|
||||||
|
|
||||||
|
/* Start tracking TLS connections in the DoS subsystem as soon as possible,
|
||||||
|
* so we can protect against attacks that use partially open connections.
|
||||||
|
*/
|
||||||
|
geoip_note_client_seen(GEOIP_CLIENT_CONNECT,
|
||||||
|
&TO_CONN(orconn)->addr, NULL,
|
||||||
|
time(NULL));
|
||||||
|
dos_new_client_conn(orconn, NULL);
|
||||||
|
|
||||||
return chan;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,6 +968,7 @@ dos_new_client_conn(or_connection_t *or_conn, const char *transport_name)
|
|||||||
clientmap_entry_t *entry;
|
clientmap_entry_t *entry;
|
||||||
|
|
||||||
tor_assert(or_conn);
|
tor_assert(or_conn);
|
||||||
|
tor_assert_nonfatal(!or_conn->tracked_for_dos_mitigation);
|
||||||
|
|
||||||
/* Past that point, we know we have at least one DoS detection subsystem
|
/* Past that point, we know we have at least one DoS detection subsystem
|
||||||
* enabled so we'll start allocating stuff. */
|
* enabled so we'll start allocating stuff. */
|
||||||
@ -975,14 +976,6 @@ dos_new_client_conn(or_connection_t *or_conn, const char *transport_name)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We ignore any known address meaning an address of a known relay. The
|
|
||||||
* reason to do so is because network reentry is possible where a client
|
|
||||||
* connection comes from an Exit node. Even when we'll fix reentry, this is
|
|
||||||
* a robust defense to keep in place. */
|
|
||||||
if (nodelist_probably_contains_address(&TO_CONN(or_conn)->addr)) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We are only interested in client connection from the geoip cache. */
|
/* We are only interested in client connection from the geoip cache. */
|
||||||
entry = geoip_lookup_client(&TO_CONN(or_conn)->addr, transport_name,
|
entry = geoip_lookup_client(&TO_CONN(or_conn)->addr, transport_name,
|
||||||
GEOIP_CLIENT_CONNECT);
|
GEOIP_CLIENT_CONNECT);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* the others, we're not.
|
* the others, we're not.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/** We've noticed a connection as a bridge relay or entry guard. */
|
/** An incoming ORPort connection */
|
||||||
GEOIP_CLIENT_CONNECT = 0,
|
GEOIP_CLIENT_CONNECT = 0,
|
||||||
/** We've served a networkstatus consensus as a directory server. */
|
/** We've served a networkstatus consensus as a directory server. */
|
||||||
GEOIP_CLIENT_NETWORKSTATUS = 1,
|
GEOIP_CLIENT_NETWORKSTATUS = 1,
|
||||||
|
@ -72,6 +72,7 @@ test_dos_conn_creation(void *arg)
|
|||||||
|
|
||||||
/* Initialize test data */
|
/* Initialize test data */
|
||||||
or_connection_t or_conn;
|
or_connection_t or_conn;
|
||||||
|
memset(&or_conn, 0, sizeof or_conn);
|
||||||
time_t wallclock_now = 1281533250; /* 2010-08-11 13:27:30 UTC */
|
time_t wallclock_now = 1281533250; /* 2010-08-11 13:27:30 UTC */
|
||||||
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
||||||
"18.0.0.1"));
|
"18.0.0.1"));
|
||||||
@ -90,6 +91,7 @@ test_dos_conn_creation(void *arg)
|
|||||||
* second for each connection. */
|
* second for each connection. */
|
||||||
monotime_coarse_set_mock_time_nsec(monotime_now += BILLION);
|
monotime_coarse_set_mock_time_nsec(monotime_now += BILLION);
|
||||||
update_approx_time(++wallclock_now);
|
update_approx_time(++wallclock_now);
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,12 +101,14 @@ test_dos_conn_creation(void *arg)
|
|||||||
dos_conn_addr_get_defense_type(addr));
|
dos_conn_addr_get_defense_type(addr));
|
||||||
|
|
||||||
/* Register another conn and check that new conns are not allowed anymore */
|
/* Register another conn and check that new conns are not allowed anymore */
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
|
tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
|
||||||
dos_conn_addr_get_defense_type(addr));
|
dos_conn_addr_get_defense_type(addr));
|
||||||
|
|
||||||
/* Close a client conn and see that a new conn will be permitted again */
|
/* Close a client conn and see that a new conn will be permitted again */
|
||||||
dos_close_client_conn(&or_conn);
|
dos_close_client_conn(&or_conn);
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
tt_int_op(DOS_CONN_DEFENSE_NONE, OP_EQ,
|
tt_int_op(DOS_CONN_DEFENSE_NONE, OP_EQ,
|
||||||
dos_conn_addr_get_defense_type(addr));
|
dos_conn_addr_get_defense_type(addr));
|
||||||
|
|
||||||
@ -150,6 +154,7 @@ test_dos_circuit_creation(void *arg)
|
|||||||
|
|
||||||
/* Initialize test data */
|
/* Initialize test data */
|
||||||
or_connection_t or_conn;
|
or_connection_t or_conn;
|
||||||
|
memset(&or_conn, 0, sizeof or_conn);
|
||||||
time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
|
time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
|
||||||
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
||||||
"18.0.0.1"));
|
"18.0.0.1"));
|
||||||
@ -165,6 +170,7 @@ test_dos_circuit_creation(void *arg)
|
|||||||
* circuit counting subsystem */
|
* circuit counting subsystem */
|
||||||
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now);
|
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now);
|
||||||
for (i = 0; i < min_conc_conns_for_cc ; i++) {
|
for (i = 0; i < min_conc_conns_for_cc ; i++) {
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +220,7 @@ test_dos_bucket_refill(void *arg)
|
|||||||
channel_init(chan);
|
channel_init(chan);
|
||||||
chan->is_client = 1;
|
chan->is_client = 1;
|
||||||
or_connection_t or_conn;
|
or_connection_t or_conn;
|
||||||
|
memset(&or_conn, 0, sizeof or_conn);
|
||||||
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
||||||
"18.0.0.1"));
|
"18.0.0.1"));
|
||||||
tor_addr_t *addr = &TO_CONN(&or_conn)->addr;
|
tor_addr_t *addr = &TO_CONN(&or_conn)->addr;
|
||||||
@ -430,12 +437,12 @@ test_dos_bucket_refill(void *arg)
|
|||||||
dos_free_all();
|
dos_free_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test if we avoid counting a known relay. */
|
/* Test if we avoid counting a known relay. (We no longer do) */
|
||||||
static void
|
static void
|
||||||
test_known_relay(void *arg)
|
test_known_relay(void *arg)
|
||||||
{
|
{
|
||||||
clientmap_entry_t *entry = NULL;
|
clientmap_entry_t *entry = NULL;
|
||||||
routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
|
routerstatus_t *rs = NULL;
|
||||||
|
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
@ -455,6 +462,7 @@ test_known_relay(void *arg)
|
|||||||
|
|
||||||
/* Setup an OR conn so we can pass it to the DoS subsystem. */
|
/* Setup an OR conn so we can pass it to the DoS subsystem. */
|
||||||
or_connection_t or_conn;
|
or_connection_t or_conn;
|
||||||
|
memset(&or_conn, 0, sizeof or_conn);
|
||||||
tor_addr_parse(&TO_CONN(&or_conn)->addr, "42.42.42.42");
|
tor_addr_parse(&TO_CONN(&or_conn)->addr, "42.42.42.42");
|
||||||
|
|
||||||
rs = tor_malloc_zero(sizeof(*rs));
|
rs = tor_malloc_zero(sizeof(*rs));
|
||||||
@ -471,34 +479,24 @@ test_known_relay(void *arg)
|
|||||||
* client connection. */
|
* client connection. */
|
||||||
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &TO_CONN(&or_conn)->addr,
|
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &TO_CONN(&or_conn)->addr,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
/* Suppose we have 5 connections in rapid succession, the counter should
|
/* Suppose we have 5 connections in rapid succession */
|
||||||
* always be 0 because we should ignore this. */
|
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
entry = geoip_lookup_client(&TO_CONN(&or_conn)->addr, NULL,
|
entry = geoip_lookup_client(&TO_CONN(&or_conn)->addr, NULL,
|
||||||
GEOIP_CLIENT_CONNECT);
|
GEOIP_CLIENT_CONNECT);
|
||||||
tt_assert(entry);
|
tt_assert(entry);
|
||||||
/* We should have a count of 0. */
|
/* We should have a count of 5. */
|
||||||
tt_uint_op(entry->dos_stats.conn_stats.concurrent_count, OP_EQ, 0);
|
tt_uint_op(entry->dos_stats.conn_stats.concurrent_count, OP_EQ, 5);
|
||||||
|
|
||||||
/* To make sure that his is working properly, make a unknown client
|
|
||||||
* connection and see if we do get it. */
|
|
||||||
tor_addr_parse(&TO_CONN(&or_conn)->addr, "42.42.42.43");
|
|
||||||
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &TO_CONN(&or_conn)->addr,
|
|
||||||
NULL, 0);
|
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
|
||||||
entry = geoip_lookup_client(&TO_CONN(&or_conn)->addr, NULL,
|
|
||||||
GEOIP_CLIENT_CONNECT);
|
|
||||||
tt_assert(entry);
|
|
||||||
/* We should have a count of 2. */
|
|
||||||
tt_uint_op(entry->dos_stats.conn_stats.concurrent_count, OP_EQ, 2);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
|
routerstatus_free(rs);
|
||||||
smartlist_clear(dummy_ns->routerstatus_list);
|
smartlist_clear(dummy_ns->routerstatus_list);
|
||||||
networkstatus_vote_free(dummy_ns);
|
networkstatus_vote_free(dummy_ns);
|
||||||
dos_free_all();
|
dos_free_all();
|
||||||
@ -520,6 +518,7 @@ test_dos_conn_rate(void *arg)
|
|||||||
|
|
||||||
/* Initialize test data */
|
/* Initialize test data */
|
||||||
or_connection_t or_conn;
|
or_connection_t or_conn;
|
||||||
|
memset(&or_conn, 0, sizeof or_conn);
|
||||||
time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
|
time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
|
||||||
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
|
||||||
"18.0.0.1"));
|
"18.0.0.1"));
|
||||||
@ -535,6 +534,7 @@ test_dos_conn_rate(void *arg)
|
|||||||
{ /* Register many conns from this client but not enough to get it blocked */
|
{ /* Register many conns from this client but not enough to get it blocked */
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < burst_conn - 1; i++) {
|
for (i = 0; i < burst_conn - 1; i++) {
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,6 +545,7 @@ test_dos_conn_rate(void *arg)
|
|||||||
|
|
||||||
/* Register another conn and check that new conns are not allowed anymore.
|
/* Register another conn and check that new conns are not allowed anymore.
|
||||||
* We should have reached our burst. */
|
* We should have reached our burst. */
|
||||||
|
or_conn.tracked_for_dos_mitigation = 0;
|
||||||
dos_new_client_conn(&or_conn, NULL);
|
dos_new_client_conn(&or_conn, NULL);
|
||||||
tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
|
tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
|
||||||
dos_conn_addr_get_defense_type(addr));
|
dos_conn_addr_get_defense_type(addr));
|
||||||
|
Loading…
Reference in New Issue
Block a user