aboutsummaryrefslogtreecommitdiff
path: root/src/core/or
diff options
context:
space:
mode:
authorMicah Elizabeth Scott <beth@torproject.org>2023-08-09 18:07:34 -0700
committerMicah Elizabeth Scott <beth@torproject.org>2023-08-09 18:07:34 -0700
commit3e18507dc75afcf0c6560e966c9f18942406b0c8 (patch)
tree70968ea83670e390e63f70d20ac2e133b53bea5c /src/core/or
parent3d63d713ea42d1ed1ca4686340cd03f82ba394b7 (diff)
downloadtor-3e18507dc75afcf0c6560e966c9f18942406b0c8.tar.gz
tor-3e18507dc75afcf0c6560e966c9f18942406b0c8.zip
Extend DoS protection to partially-open channels
tor only marks a channel as 'open' once the TLS and OR handshakes have both completed, and normal "client" (ORPort) DoS protection is not enabled until the channel becomes open. This patch adds an additional earlier initialization path for DoS protection on incoming TLS connections. This leaves the existing dos_new_client_conn() call sites intact, but adds a guard against multiple-initialization using the existing tracked_for_dos_mitigation flag. Other types of channels shouldn't be affected by this patch.
Diffstat (limited to 'src/core/or')
-rw-r--r--src/core/or/channel.c29
-rw-r--r--src/core/or/channeltls.c10
-rw-r--r--src/core/or/dos.c1
3 files changed, 27 insertions, 13 deletions
diff --git a/src/core/or/channel.c b/src/core/or/channel.c
index 9d15d35ac9..b5b3f4c4f0 100644
--- a/src/core/or/channel.c
+++ b/src/core/or/channel.c
@@ -83,6 +83,7 @@
#include "lib/time/compat_time.h"
#include "core/or/cell_queue_st.h"
+#include "core/or/or_connection_st.h"
/* Global lists of channels */
@@ -1864,7 +1865,6 @@ channel_do_open_actions(channel_t *chan)
{
tor_addr_t remote_addr;
int started_here;
- time_t now = time(NULL);
int close_origin_circuits = 0;
tor_assert(chan);
@@ -1875,22 +1875,25 @@ channel_do_open_actions(channel_t *chan)
circuit_build_times_network_is_live(get_circuit_build_times_mutable());
router_set_status(chan->identity_digest, 1);
} 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_get_addr_if_possible(chan, &remote_addr)) {
- char *transport_name = NULL;
channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
- if (chan->get_transport_name(chan, &transport_name) < 0)
- transport_name = NULL;
-
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT,
- &remote_addr, transport_name,
- now);
- /* Notify the DoS subsystem of a new client. */
- if (tlschan && tlschan->conn) {
- dos_new_client_conn(tlschan->conn, transport_name);
+ if (!tlschan->conn->tracked_for_dos_mitigation) {
+ char *transport_name = NULL;
+ if (chan->get_transport_name(chan, &transport_name) < 0) {
+ transport_name = NULL;
+ }
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT,
+ &remote_addr, transport_name,
+ time(NULL));
+ if (tlschan && tlschan->conn) {
+ 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 */
}
diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c
index 9db8e2392d..1f5a466777 100644
--- a/src/core/or/channeltls.c
+++ b/src/core/or/channeltls.c
@@ -44,6 +44,7 @@
#include "core/or/circuitmux.h"
#include "core/or/circuitmux_ewma.h"
#include "core/or/command.h"
+#include "core/or/dos.h"
#include "app/config/config.h"
#include "app/config/resolve_addr.h"
#include "core/mainloop/connection.h"
@@ -54,6 +55,7 @@
#include "trunnel/link_handshake.h"
#include "core/or/relay.h"
#include "feature/stats/rephist.h"
+#include "feature/stats/geoip_stats.h"
#include "feature/relay/router.h"
#include "feature/relay/routermode.h"
#include "feature/nodelist/dirlist.h"
@@ -358,6 +360,14 @@ channel_tls_handle_incoming(or_connection_t *orconn)
/* Register it */
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;
}
diff --git a/src/core/or/dos.c b/src/core/or/dos.c
index 8e0fe9e641..b9f8eb22f2 100644
--- a/src/core/or/dos.c
+++ b/src/core/or/dos.c
@@ -968,6 +968,7 @@ dos_new_client_conn(or_connection_t *or_conn, const char *transport_name)
clientmap_entry_t *entry;
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
* enabled so we'll start allocating stuff. */