1 /* Copyright (c) 2018-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
6 * \brief Implement Denial of Service mitigation subsystem.
11 #include "core/or/or.h"
12 #include "app/config/config.h"
13 #include "core/mainloop/connection.h"
14 #include "core/mainloop/mainloop.h"
15 #include "core/or/channel.h"
16 #include "core/or/connection_or.h"
17 #include "core/or/relay.h"
18 #include "feature/hs/hs_dos.h"
19 #include "feature/nodelist/networkstatus.h"
20 #include "feature/nodelist/nodelist.h"
21 #include "feature/relay/routermode.h"
22 #include "feature/stats/geoip_stats.h"
23 #include "lib/crypt_ops/crypto_rand.h"
24 #include "lib/time/compat_time.h"
26 #include "core/or/dos.h"
27 #include "core/or/dos_sys.h"
29 #include "core/or/dos_options_st.h"
30 #include "core/or/or_connection_st.h"
33 * Circuit creation denial of service mitigation.
35 * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for
39 /* Is the circuit creation DoS mitigation enabled? */
40 static unsigned int dos_cc_enabled
= 0;
42 /* Consensus parameters. They can be changed when a new consensus arrives.
43 * They are initialized with the hardcoded default values. */
44 static uint32_t dos_cc_min_concurrent_conn
;
45 static uint32_t dos_cc_circuit_rate
;
46 static uint32_t dos_cc_circuit_burst
;
47 static dos_cc_defense_type_t dos_cc_defense_type
;
48 static int32_t dos_cc_defense_time_period
;
50 /* Keep some stats for the heartbeat so we can report out. */
51 static uint64_t cc_num_rejected_cells
;
52 static uint32_t cc_num_marked_addrs
;
53 static uint32_t cc_num_marked_addrs_max_queue
;
56 * Concurrent connection denial of service mitigation.
58 * Namespace used for this mitigation framework is "dos_conn_".
61 /* Is the connection DoS mitigation enabled? */
62 static unsigned int dos_conn_enabled
= 0;
64 /* Consensus parameters. They can be changed when a new consensus arrives.
65 * They are initialized with the hardcoded default values. */
66 static uint32_t dos_conn_max_concurrent_count
;
67 static dos_conn_defense_type_t dos_conn_defense_type
;
68 static uint32_t dos_conn_connect_rate
= DOS_CONN_CONNECT_RATE_DEFAULT
;
69 static uint32_t dos_conn_connect_burst
= DOS_CONN_CONNECT_BURST_DEFAULT
;
70 static int32_t dos_conn_connect_defense_time_period
=
71 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT
;
73 /* Keep some stats for the heartbeat so we can report out. */
74 static uint64_t conn_num_addr_rejected
;
75 static uint64_t conn_num_addr_connect_rejected
;
77 /** Consensus parameter: How many times a client IP is allowed to hit the
78 * circ_max_cell_queue_size_out limit before being marked. */
79 static uint32_t dos_num_circ_max_outq
;
82 * Stream denial of service mitigation.
84 * Namespace used for this mitigation framework is "dos_stream_".
87 /* Is the connection DoS mitigation enabled? */
88 static unsigned int dos_stream_enabled
= 0;
90 /* Consensus parameters. They can be changed when a new consensus arrives.
91 * They are initialized with the hardcoded default values. */
92 static dos_stream_defense_type_t dos_stream_defense_type
;
93 static uint32_t dos_stream_rate
= DOS_STREAM_RATE_DEFAULT
;
94 static uint32_t dos_stream_burst
= DOS_STREAM_BURST_DEFAULT
;
96 /* Keep some stats for the heartbeat so we can report out. */
97 static uint64_t stream_num_rejected
;
100 * General interface of the denial of service mitigation subsystem.
103 /* Keep stats for the heartbeat. */
104 static uint64_t num_single_hop_client_refused
;
106 /** Return the consensus parameter for the outbound circ_max_cell_queue_size
109 get_param_dos_num_circ_max_outq(const networkstatus_t
*ns
)
111 #define DOS_NUM_CIRC_MAX_OUTQ_DEFAULT 3
112 #define DOS_NUM_CIRC_MAX_OUTQ_MIN 0
113 #define DOS_NUM_CIRC_MAX_OUTQ_MAX INT32_MAX
115 /* Update the circuit max cell queue size from the consensus. */
116 return networkstatus_get_param(ns
, "dos_num_circ_max_outq",
117 DOS_NUM_CIRC_MAX_OUTQ_DEFAULT
,
118 DOS_NUM_CIRC_MAX_OUTQ_MIN
,
119 DOS_NUM_CIRC_MAX_OUTQ_MAX
);
122 /* Return true iff the circuit creation mitigation is enabled. We look at the
123 * consensus for this else a default value is returned. */
124 MOCK_IMPL(STATIC
unsigned int,
125 get_param_cc_enabled
, (const networkstatus_t
*ns
))
127 if (dos_get_options()->DoSCircuitCreationEnabled
!= -1) {
128 return dos_get_options()->DoSCircuitCreationEnabled
;
131 return !!networkstatus_get_param(ns
, "DoSCircuitCreationEnabled",
132 DOS_CC_ENABLED_DEFAULT
, 0, 1);
135 /* Return the parameter for the minimum concurrent connection at which we'll
136 * start counting circuit for a specific client address. */
138 get_param_cc_min_concurrent_connection(const networkstatus_t
*ns
)
140 if (dos_get_options()->DoSCircuitCreationMinConnections
) {
141 return dos_get_options()->DoSCircuitCreationMinConnections
;
143 return networkstatus_get_param(ns
, "DoSCircuitCreationMinConnections",
144 DOS_CC_MIN_CONCURRENT_CONN_DEFAULT
,
148 /* Return the parameter for the time rate that is how many circuits over this
151 get_param_cc_circuit_rate(const networkstatus_t
*ns
)
153 /* This is in seconds. */
154 if (dos_get_options()->DoSCircuitCreationRate
) {
155 return dos_get_options()->DoSCircuitCreationRate
;
157 return networkstatus_get_param(ns
, "DoSCircuitCreationRate",
158 DOS_CC_CIRCUIT_RATE_DEFAULT
,
162 /* Return the parameter for the maximum circuit count for the circuit time
165 get_param_cc_circuit_burst(const networkstatus_t
*ns
)
167 if (dos_get_options()->DoSCircuitCreationBurst
) {
168 return dos_get_options()->DoSCircuitCreationBurst
;
170 return networkstatus_get_param(ns
, "DoSCircuitCreationBurst",
171 DOS_CC_CIRCUIT_BURST_DEFAULT
,
175 /* Return the consensus parameter of the circuit creation defense type. */
177 get_param_cc_defense_type(const networkstatus_t
*ns
)
179 if (dos_get_options()->DoSCircuitCreationDefenseType
) {
180 return dos_get_options()->DoSCircuitCreationDefenseType
;
182 return networkstatus_get_param(ns
, "DoSCircuitCreationDefenseType",
183 DOS_CC_DEFENSE_TYPE_DEFAULT
,
184 DOS_CC_DEFENSE_NONE
, DOS_CC_DEFENSE_MAX
);
187 /* Return the consensus parameter of the defense time period which is how much
188 * time should we defend against a malicious client address. */
190 get_param_cc_defense_time_period(const networkstatus_t
*ns
)
192 /* Time in seconds. */
193 if (dos_get_options()->DoSCircuitCreationDefenseTimePeriod
) {
194 return dos_get_options()->DoSCircuitCreationDefenseTimePeriod
;
196 return networkstatus_get_param(ns
, "DoSCircuitCreationDefenseTimePeriod",
197 DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT
,
201 /* Return true iff connection mitigation is enabled. We look at the consensus
202 * for this else a default value is returned. */
203 MOCK_IMPL(STATIC
unsigned int,
204 get_param_conn_enabled
, (const networkstatus_t
*ns
))
206 if (dos_get_options()->DoSConnectionEnabled
!= -1) {
207 return dos_get_options()->DoSConnectionEnabled
;
209 return !!networkstatus_get_param(ns
, "DoSConnectionEnabled",
210 DOS_CONN_ENABLED_DEFAULT
, 0, 1);
213 /* Return the consensus parameter for the maximum concurrent connection
216 get_param_conn_max_concurrent_count(const networkstatus_t
*ns
)
218 if (dos_get_options()->DoSConnectionMaxConcurrentCount
) {
219 return dos_get_options()->DoSConnectionMaxConcurrentCount
;
221 return networkstatus_get_param(ns
, "DoSConnectionMaxConcurrentCount",
222 DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT
,
226 /* Return the consensus parameter of the connection defense type. */
228 get_param_conn_defense_type(const networkstatus_t
*ns
)
230 if (dos_get_options()->DoSConnectionDefenseType
) {
231 return dos_get_options()->DoSConnectionDefenseType
;
233 return networkstatus_get_param(ns
, "DoSConnectionDefenseType",
234 DOS_CONN_DEFENSE_TYPE_DEFAULT
,
235 DOS_CONN_DEFENSE_NONE
, DOS_CONN_DEFENSE_MAX
);
238 /* Return the connection connect rate parameters either from the configuration
239 * file or, if not found, consensus parameter. */
241 get_param_conn_connect_rate(const networkstatus_t
*ns
)
243 if (dos_get_options()->DoSConnectionConnectRate
) {
244 return dos_get_options()->DoSConnectionConnectRate
;
246 return networkstatus_get_param(ns
, "DoSConnectionConnectRate",
247 DOS_CONN_CONNECT_RATE_DEFAULT
,
251 /* Return the connection connect burst parameters either from the
252 * configuration file or, if not found, consensus parameter. */
254 get_param_conn_connect_burst(const networkstatus_t
*ns
)
256 if (dos_get_options()->DoSConnectionConnectBurst
) {
257 return dos_get_options()->DoSConnectionConnectBurst
;
259 return networkstatus_get_param(ns
, "DoSConnectionConnectBurst",
260 DOS_CONN_CONNECT_BURST_DEFAULT
,
264 /* Return the connection connect defense time period from the configuration
265 * file or, if not found, the consensus parameter. */
267 get_param_conn_connect_defense_time_period(const networkstatus_t
*ns
)
269 /* Time in seconds. */
270 if (dos_get_options()->DoSConnectionConnectDefenseTimePeriod
) {
271 return dos_get_options()->DoSConnectionConnectDefenseTimePeriod
;
273 return networkstatus_get_param(ns
, "DoSConnectionConnectDefenseTimePeriod",
274 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT
,
275 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_MIN
,
279 /* Return true iff the stream creation mitigation is enabled. We look at the
280 * consensus for this else a default value is returned. */
281 MOCK_IMPL(STATIC
unsigned int,
282 get_param_stream_enabled
, (const networkstatus_t
*ns
))
284 if (dos_get_options()->DoSStreamCreationEnabled
!= -1) {
285 return dos_get_options()->DoSStreamCreationEnabled
;
288 return !!networkstatus_get_param(ns
, "DoSStreamCreationEnabled",
289 DOS_STREAM_ENABLED_DEFAULT
, 0, 1);
292 /* Return the parameter for the time rate that is how many stream per circuit
293 * over this time span. */
295 get_param_stream_rate(const networkstatus_t
*ns
)
297 /* This is in seconds. */
298 if (dos_get_options()->DoSStreamCreationRate
) {
299 return dos_get_options()->DoSStreamCreationRate
;
301 return networkstatus_get_param(ns
, "DoSStreamCreationRate",
302 DOS_STREAM_RATE_DEFAULT
,
306 /* Return the parameter for the maximum circuit count for the circuit time
309 get_param_stream_burst(const networkstatus_t
*ns
)
311 if (dos_get_options()->DoSStreamCreationBurst
) {
312 return dos_get_options()->DoSStreamCreationBurst
;
314 return networkstatus_get_param(ns
, "DoSStreamCreationBurst",
315 DOS_STREAM_BURST_DEFAULT
,
319 /* Return the consensus parameter of the circuit creation defense type. */
321 get_param_stream_defense_type(const networkstatus_t
*ns
)
323 if (dos_get_options()->DoSStreamCreationDefenseType
) {
324 return dos_get_options()->DoSStreamCreationDefenseType
;
326 return networkstatus_get_param(ns
, "DoSStreamCreationDefenseType",
327 DOS_STREAM_DEFENSE_TYPE_DEFAULT
,
328 DOS_STREAM_DEFENSE_NONE
,
329 DOS_STREAM_DEFENSE_MAX
);
332 /* Set circuit creation parameters located in the consensus or their default
333 * if none are present. Called at initialization or when the consensus
336 set_dos_parameters(const networkstatus_t
*ns
)
338 /* Get the default consensus param values. */
339 dos_cc_enabled
= get_param_cc_enabled(ns
);
340 dos_cc_min_concurrent_conn
= get_param_cc_min_concurrent_connection(ns
);
341 dos_cc_circuit_rate
= get_param_cc_circuit_rate(ns
);
342 dos_cc_circuit_burst
= get_param_cc_circuit_burst(ns
);
343 dos_cc_defense_time_period
= get_param_cc_defense_time_period(ns
);
344 dos_cc_defense_type
= get_param_cc_defense_type(ns
);
346 /* Connection detection. */
347 dos_conn_enabled
= get_param_conn_enabled(ns
);
348 dos_conn_max_concurrent_count
= get_param_conn_max_concurrent_count(ns
);
349 dos_conn_defense_type
= get_param_conn_defense_type(ns
);
350 dos_conn_connect_rate
= get_param_conn_connect_rate(ns
);
351 dos_conn_connect_burst
= get_param_conn_connect_burst(ns
);
352 dos_conn_connect_defense_time_period
=
353 get_param_conn_connect_defense_time_period(ns
);
356 dos_num_circ_max_outq
= get_param_dos_num_circ_max_outq(ns
);
359 dos_stream_enabled
= get_param_stream_enabled(ns
);
360 dos_stream_defense_type
= get_param_stream_defense_type(ns
);
361 dos_stream_rate
= get_param_stream_rate(ns
);
362 dos_stream_burst
= get_param_stream_burst(ns
);
365 /* Free everything for the circuit creation DoS mitigation subsystem. */
369 /* If everything is freed, the circuit creation subsystem is not enabled. */
373 /* Called when the consensus has changed. Do appropriate actions for the
374 * circuit creation subsystem. */
376 cc_consensus_has_changed(const networkstatus_t
*ns
)
378 /* Looking at the consensus, is the circuit creation subsystem enabled? If
379 * not and it was enabled before, clean it up. */
380 if (dos_cc_enabled
&& !get_param_cc_enabled(ns
)) {
385 /** Return the number of circuits we allow per second under the current
388 get_circuit_rate_per_second(void)
390 return dos_cc_circuit_rate
;
393 /* Given the circuit creation client statistics object, refill the circuit
394 * bucket if needed. This also works if the bucket was never filled in the
395 * first place. The addr is only used for logging purposes. */
397 cc_stats_refill_bucket(cc_client_stats_t
*stats
, const tor_addr_t
*addr
)
399 uint32_t new_circuit_bucket_count
;
400 uint64_t num_token
, elapsed_time_last_refill
= 0, circuit_rate
= 0;
402 int64_t last_refill_ts
;
408 last_refill_ts
= (int64_t)stats
->last_circ_bucket_refill_ts
;
410 /* If less than a second has elapsed, don't add any tokens.
411 * Note: If a relay's clock is ever 0, any new clients won't get a refill
412 * until the next second. But a relay that thinks it is 1970 will never
413 * validate the public consensus. */
414 if ((int64_t)now
== last_refill_ts
) {
418 /* At this point, we know we might need to add token to the bucket. We'll
419 * first get the circuit rate that is how many circuit are we allowed to do
421 circuit_rate
= get_circuit_rate_per_second();
423 /* We've never filled the bucket so fill it with the maximum being the burst
425 * Note: If a relay's clock is ever 0, all clients that were last refilled
426 * in that zero second will get a full refill here. */
427 if (last_refill_ts
== 0) {
428 num_token
= dos_cc_circuit_burst
;
432 /* Our clock jumped backward so fill it up to the maximum. Not filling it
433 * could trigger a detection for a valid client. Also, if the clock jumped
434 * negative but we didn't notice until the elapsed time became positive
435 * again, then we potentially spent many seconds not refilling the bucket
436 * when we should have been refilling it. But the fact that we didn't notice
437 * until now means that no circuit creation requests came in during that
438 * time, so the client doesn't end up punished that much from this hopefully
440 if ((int64_t)now
< last_refill_ts
) {
441 /* Use the maximum allowed value of token. */
442 num_token
= dos_cc_circuit_burst
;
446 /* How many seconds have elapsed between now and the last refill?
447 * This subtraction can't underflow, because now >= last_refill_ts.
448 * And it can't overflow, because INT64_MAX - (-INT64_MIN) == UINT64_MAX. */
449 elapsed_time_last_refill
= (uint64_t)now
- last_refill_ts
;
451 /* If the elapsed time is very large, it means our clock jumped forward.
452 * If the multiplication would overflow, use the maximum allowed value. */
453 if (elapsed_time_last_refill
> UINT32_MAX
) {
454 num_token
= dos_cc_circuit_burst
;
458 /* Compute how many circuits we are allowed in that time frame which we'll
459 * add to the bucket. This can't overflow, because both multiplicands
460 * are less than or equal to UINT32_MAX, and num_token is uint64_t. */
461 num_token
= elapsed_time_last_refill
* circuit_rate
;
464 /* If the sum would overflow, use the maximum allowed value. */
465 if (num_token
> UINT32_MAX
- stats
->circuit_bucket
) {
466 new_circuit_bucket_count
= dos_cc_circuit_burst
;
468 /* We cap the bucket to the burst value else this could overflow uint32_t
470 new_circuit_bucket_count
= MIN(stats
->circuit_bucket
+ (uint32_t)num_token
,
471 dos_cc_circuit_burst
);
474 /* This function is not allowed to make the bucket count larger than the
476 tor_assert_nonfatal(new_circuit_bucket_count
<= dos_cc_circuit_burst
);
477 /* This function is not allowed to make the bucket count smaller, unless it
478 * is decreasing it to a newly configured, lower burst value. We allow the
479 * bucket to stay the same size, in case the circuit rate is zero. */
480 tor_assert_nonfatal(new_circuit_bucket_count
>= stats
->circuit_bucket
||
481 new_circuit_bucket_count
== dos_cc_circuit_burst
);
483 log_debug(LD_DOS
, "DoS address %s has its circuit bucket value: %" PRIu32
484 ". Filling it to %" PRIu32
". Circuit rate is %" PRIu64
485 ". Elapsed time is %" PRIi64
,
486 fmt_addr(addr
), stats
->circuit_bucket
, new_circuit_bucket_count
,
487 circuit_rate
, (int64_t)elapsed_time_last_refill
);
489 stats
->circuit_bucket
= new_circuit_bucket_count
;
490 stats
->last_circ_bucket_refill_ts
= now
;
496 /* Return true iff the circuit bucket is down to 0 and the number of
497 * concurrent connections is greater or equal the minimum threshold set the
498 * consensus parameter. */
500 cc_has_exhausted_circuits(const dos_client_stats_t
*stats
)
503 return stats
->cc_stats
.circuit_bucket
== 0 &&
504 stats
->conn_stats
.concurrent_count
>= dos_cc_min_concurrent_conn
;
507 /* Mark client address by setting a timestamp in the stats object which tells
508 * us until when it is marked as positively detected. */
510 cc_mark_client(cc_client_stats_t
*stats
)
513 /* We add a random offset of a maximum of half the defense time so it is
514 * less predictable. */
515 stats
->marked_until_ts
=
516 approx_time() + dos_cc_defense_time_period
+
517 crypto_rand_int_range(1, dos_cc_defense_time_period
/ 2);
520 /* Return true iff the given channel address is marked as malicious. This is
521 * called a lot and part of the fast path of handling cells. It has to remain
522 * as fast as we can. */
524 cc_channel_addr_is_marked(channel_t
*chan
)
528 clientmap_entry_t
*entry
;
529 cc_client_stats_t
*stats
= NULL
;
534 /* Must be a client connection else we ignore. */
535 if (!channel_is_client(chan
)) {
538 /* Without an IP address, nothing can work. */
539 if (!channel_get_addr_if_possible(chan
, &addr
)) {
543 /* We are only interested in client connection from the geoip cache. */
544 entry
= geoip_lookup_client(&addr
, NULL
, GEOIP_CLIENT_CONNECT
);
546 /* We can have a connection creating circuits but not tracked by the geoip
547 * cache. Once this DoS subsystem is enabled, we can end up here with no
548 * entry for the channel. */
552 stats
= &entry
->dos_stats
.cc_stats
;
555 return stats
&& stats
->marked_until_ts
>= now
;
558 /* Concurrent connection private API. */
560 /* Mark client connection stats by setting a timestamp which tells us until
561 * when it is marked as positively detected. */
563 conn_mark_client(conn_client_stats_t
*stats
)
567 /* We add a random offset of a maximum of half the defense time so it is
568 * less predictable and thus more difficult to game. */
569 stats
->marked_until_ts
=
570 approx_time() + dos_conn_connect_defense_time_period
+
571 crypto_rand_int_range(1, dos_conn_connect_defense_time_period
/ 2);
574 /* Free everything for the connection DoS mitigation subsystem. */
578 dos_conn_enabled
= 0;
581 /* Called when the consensus has changed. Do appropriate actions for the
582 * connection mitigation subsystem. */
584 conn_consensus_has_changed(const networkstatus_t
*ns
)
586 /* Looking at the consensus, is the connection mitigation subsystem enabled?
587 * If not and it was enabled before, clean it up. */
588 if (dos_conn_enabled
&& !get_param_conn_enabled(ns
)) {
593 /** Called when a new client connection has arrived. The following will update
594 * the client connection statistics.
596 * The addr is used for logging purposes only.
598 * If the connect counter reaches its limit, it is marked. */
600 conn_update_on_connect(conn_client_stats_t
*stats
, const tor_addr_t
*addr
)
605 /* Update concurrent count for this new connect. */
606 stats
->concurrent_count
++;
608 /* Refill connect connection count. */
609 token_bucket_ctr_refill(&stats
->connect_count
,
610 (uint32_t) monotime_coarse_absolute_sec());
612 /* Decrement counter for this new connection. */
613 if (token_bucket_ctr_get(&stats
->connect_count
) > 0) {
614 token_bucket_ctr_dec(&stats
->connect_count
, 1);
617 /* Assess connect counter. Mark it if counter is down to 0 and we haven't
618 * marked it before or it was reset. This is to avoid to re-mark it over and
619 * over again extending continuously the blocked time. */
620 if (token_bucket_ctr_get(&stats
->connect_count
) == 0 &&
621 stats
->marked_until_ts
== 0) {
622 conn_mark_client(stats
);
625 log_debug(LD_DOS
, "Client address %s has now %u concurrent connections. "
626 "Remaining %" TOR_PRIuSZ
"/sec connections are allowed.",
627 fmt_addr(addr
), stats
->concurrent_count
,
628 token_bucket_ctr_get(&stats
->connect_count
));
631 /** Called when a client connection is closed. The following will update
632 * the client connection statistics.
634 * The addr is used for logging purposes only. */
636 conn_update_on_close(conn_client_stats_t
*stats
, const tor_addr_t
*addr
)
638 /* Extra super duper safety. Going below 0 means an underflow which could
639 * lead to most likely a false positive. In theory, this should never happen
640 * but let's be extra safe. */
641 if (BUG(stats
->concurrent_count
== 0)) {
645 stats
->concurrent_count
--;
646 log_debug(LD_DOS
, "Client address %s has lost a connection. Concurrent "
647 "connections are now at %u",
648 fmt_addr(addr
), stats
->concurrent_count
);
651 /* General private API */
653 /* Return true iff we have at least one DoS detection enabled. This is used to
654 * decide if we need to allocate any kind of high level DoS object. */
658 return (dos_cc_enabled
|| dos_conn_enabled
);
661 /* Circuit creation public API. */
663 /** Return the number of rejected circuits. */
665 dos_get_num_cc_rejected(void)
667 return cc_num_rejected_cells
;
670 /** Return the number of marked addresses. */
672 dos_get_num_cc_marked_addr(void)
674 return cc_num_marked_addrs
;
677 /** Return the number of marked addresses due to max queue limit reached. */
679 dos_get_num_cc_marked_addr_maxq(void)
681 return cc_num_marked_addrs_max_queue
;
684 /** Return number of concurrent connections rejected. */
686 dos_get_num_conn_addr_rejected(void)
688 return conn_num_addr_rejected
;
691 /** Return the number of connection rejected. */
693 dos_get_num_conn_addr_connect_rejected(void)
695 return conn_num_addr_connect_rejected
;
698 /** Return the number of single hop refused. */
700 dos_get_num_single_hop_refused(void)
702 return num_single_hop_client_refused
;
705 /* Called when a CREATE cell is received from the given channel. */
707 dos_cc_new_create_cell(channel_t
*chan
)
710 clientmap_entry_t
*entry
;
714 /* Skip everything if not enabled. */
715 if (!dos_cc_enabled
) {
719 /* Must be a client connection else we ignore. */
720 if (!channel_is_client(chan
)) {
723 /* Without an IP address, nothing can work. */
724 if (!channel_get_addr_if_possible(chan
, &addr
)) {
728 /* We are only interested in client connection from the geoip cache. */
729 entry
= geoip_lookup_client(&addr
, NULL
, GEOIP_CLIENT_CONNECT
);
731 /* We can have a connection creating circuits but not tracked by the geoip
732 * cache. Once this DoS subsystem is enabled, we can end up here with no
733 * entry for the channel. */
737 /* General comment. Even though the client can already be marked as
738 * malicious, we continue to track statistics. If it keeps going above
739 * threshold while marked, the defense period time will grow longer. There
740 * is really no point at unmarking a client that keeps DoSing us. */
742 /* First of all, we'll try to refill the circuit bucket opportunistically
743 * before we assess. */
744 cc_stats_refill_bucket(&entry
->dos_stats
.cc_stats
, &addr
);
746 /* Take a token out of the circuit bucket if we are above 0 so we don't
747 * underflow the bucket. */
748 if (entry
->dos_stats
.cc_stats
.circuit_bucket
> 0) {
749 entry
->dos_stats
.cc_stats
.circuit_bucket
--;
752 /* This is the detection. Assess at every CREATE cell if the client should
753 * get marked as malicious. This should be kept as fast as possible. */
754 if (cc_has_exhausted_circuits(&entry
->dos_stats
)) {
755 /* If this is the first time we mark this entry, log it.
756 * Under heavy DDoS, logging each time we mark would results in lots and
758 if (entry
->dos_stats
.cc_stats
.marked_until_ts
== 0) {
759 log_debug(LD_DOS
, "Detected circuit creation DoS by address: %s",
761 cc_num_marked_addrs
++;
763 cc_mark_client(&entry
->dos_stats
.cc_stats
);
770 /* Return the defense type that should be used for this circuit.
772 * This is part of the fast path and called a lot. */
773 dos_cc_defense_type_t
774 dos_cc_get_defense_type(channel_t
*chan
)
778 /* Skip everything if not enabled. */
779 if (!dos_cc_enabled
) {
783 /* On an OR circuit, we'll check if the previous channel is a marked client
784 * connection detected by our DoS circuit creation mitigation subsystem. */
785 if (cc_channel_addr_is_marked(chan
)) {
786 /* We've just assess that this circuit should trigger a defense for the
787 * cell it just seen. Note it down. */
788 cc_num_rejected_cells
++;
789 return dos_cc_defense_type
;
793 return DOS_CC_DEFENSE_NONE
;
796 /* Concurrent connection detection public API. */
798 /* Return true iff the given address is permitted to open another connection.
799 * A defense value is returned for the caller to take appropriate actions. */
800 dos_conn_defense_type_t
801 dos_conn_addr_get_defense_type(const tor_addr_t
*addr
)
803 clientmap_entry_t
*entry
;
807 /* Skip everything if not enabled. */
808 if (!dos_conn_enabled
) {
812 /* We are only interested in client connection from the geoip cache. */
813 entry
= geoip_lookup_client(addr
, NULL
, GEOIP_CLIENT_CONNECT
);
818 /* Is this address marked as making too many client connections? */
819 if (entry
->dos_stats
.conn_stats
.marked_until_ts
>= approx_time()) {
820 conn_num_addr_connect_rejected
++;
821 return dos_conn_defense_type
;
823 /* Reset it to 0 here so that if the marked timestamp has expired that is
824 * we've gone beyond it, we have to reset it so the detection can mark it
825 * again in the future. */
826 entry
->dos_stats
.conn_stats
.marked_until_ts
= 0;
828 /* Need to be above the maximum concurrent connection count to trigger a
830 if (entry
->dos_stats
.conn_stats
.concurrent_count
>
831 dos_conn_max_concurrent_count
) {
832 conn_num_addr_rejected
++;
833 return dos_conn_defense_type
;
837 return DOS_CONN_DEFENSE_NONE
;
840 /* Stream creation public API. */
842 /** Return the number of rejected stream and resolve. */
844 dos_get_num_stream_rejected(void)
846 return stream_num_rejected
;
849 /* Return the action to take against a BEGIN or RESOLVE cell. Return
850 * DOS_STREAM_DEFENSE_NONE when no action should be taken.
851 * Increment the appropriate counter when the cell was found to go over a
853 dos_stream_defense_type_t
854 dos_stream_new_begin_or_resolve_cell(or_circuit_t
*circ
)
856 if (!dos_stream_enabled
|| circ
== NULL
)
857 return DOS_STREAM_DEFENSE_NONE
;
859 token_bucket_ctr_refill(&circ
->stream_limiter
,
860 (uint32_t) monotime_coarse_absolute_sec());
862 if (token_bucket_ctr_get(&circ
->stream_limiter
) > 0) {
863 token_bucket_ctr_dec(&circ
->stream_limiter
, 1);
864 return DOS_STREAM_DEFENSE_NONE
;
866 /* if defense type is DOS_STREAM_DEFENSE_NONE but DoSStreamEnabled is true,
867 * we count offending cells as rejected, despite them being actually
869 ++stream_num_rejected
;
870 return dos_stream_defense_type
;
873 /* Initialize the token bucket for stream rate limit on a circuit. */
875 dos_stream_init_circ_tbf(or_circuit_t
*circ
)
877 token_bucket_ctr_init(&circ
->stream_limiter
, dos_stream_rate
,
879 (uint32_t) monotime_coarse_absolute_sec());
884 /* Take any appropriate actions for the given geoip entry that is about to get
885 * freed. This is called for every entry that is being freed.
887 * This function will clear out the connection tracked flag if the concurrent
888 * count of the entry is above 0 so if those connections end up being seen by
889 * this subsystem, we won't try to decrement the counter for a new geoip entry
890 * that might have been added after this call for the same address. */
892 dos_geoip_entry_about_to_free(const clientmap_entry_t
*geoip_ent
)
894 tor_assert(geoip_ent
);
896 /* The count is down to 0 meaning no connections right now, we can safely
897 * clear the geoip entry from the cache. */
898 if (geoip_ent
->dos_stats
.conn_stats
.concurrent_count
== 0) {
902 /* For each connection matching the geoip entry address, we'll clear the
903 * tracked flag because the entry is about to get removed from the geoip
904 * cache. We do not try to decrement if the flag is not set. */
905 SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t
*, conn
) {
906 if (conn
->type
== CONN_TYPE_OR
) {
907 or_connection_t
*or_conn
= TO_OR_CONN(conn
);
908 if (!tor_addr_compare(&geoip_ent
->addr
, &TO_CONN(or_conn
)->addr
,
910 or_conn
->tracked_for_dos_mitigation
= 0;
913 } SMARTLIST_FOREACH_END(conn
);
919 /** A new geoip client entry has been allocated, initialize its DoS object. */
921 dos_geoip_entry_init(clientmap_entry_t
*geoip_ent
)
923 tor_assert(geoip_ent
);
925 /* Initialize the connection count counter with the rate and burst
926 * parameters taken either from configuration or consensus.
928 * We do this even if the DoS connection detection is not enabled because it
929 * can be enabled at runtime and these counters need to be valid. */
930 token_bucket_ctr_init(&geoip_ent
->dos_stats
.conn_stats
.connect_count
,
931 dos_conn_connect_rate
, dos_conn_connect_burst
,
932 (uint32_t) monotime_coarse_absolute_sec());
935 /** Note that the given channel has sent outbound the maximum amount of cell
936 * allowed on the next channel. */
938 dos_note_circ_max_outq(const channel_t
*chan
)
941 clientmap_entry_t
*entry
;
945 /* Skip everything if circuit creation defense is disabled. */
946 if (!dos_cc_enabled
) {
950 /* Must be a client connection else we ignore. */
951 if (!channel_is_client(chan
)) {
954 /* Without an IP address, nothing can work. */
955 if (!channel_get_addr_if_possible(chan
, &addr
)) {
959 /* We are only interested in client connection from the geoip cache. */
960 entry
= geoip_lookup_client(&addr
, NULL
, GEOIP_CLIENT_CONNECT
);
965 /* Is the client marked? If yes, just ignore. */
966 if (entry
->dos_stats
.cc_stats
.marked_until_ts
>= approx_time()) {
970 /* If max outq parameter is 0, it means disabled, just ignore. */
971 if (dos_num_circ_max_outq
== 0) {
975 entry
->dos_stats
.num_circ_max_cell_queue_size
++;
977 /* This is the detection. If we have reached the maximum amount of times a
978 * client IP is allowed to reach this limit, mark client. */
979 if (entry
->dos_stats
.num_circ_max_cell_queue_size
>=
980 dos_num_circ_max_outq
) {
981 /* Only account for this marked address if this is the first time we block
982 * it else our counter is inflated with non unique entries. */
983 if (entry
->dos_stats
.cc_stats
.marked_until_ts
== 0) {
984 cc_num_marked_addrs_max_queue
++;
986 log_info(LD_DOS
, "Detected outbound max circuit queue from addr: %s",
988 cc_mark_client(&entry
->dos_stats
.cc_stats
);
990 /* Reset after being marked so once unmarked, we start back clean. */
991 entry
->dos_stats
.num_circ_max_cell_queue_size
= 0;
998 /* Note down that we've just refused a single hop client. This increments a
999 * counter later used for the heartbeat. */
1001 dos_note_refuse_single_hop_client(void)
1003 num_single_hop_client_refused
++;
1006 /* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
1009 dos_should_refuse_single_hop_client(void)
1011 /* If we aren't a public relay, this shouldn't apply to anything. */
1012 if (!public_server_mode(get_options())) {
1016 if (dos_get_options()->DoSRefuseSingleHopClientRendezvous
!= -1) {
1017 return dos_get_options()->DoSRefuseSingleHopClientRendezvous
;
1020 return (int) networkstatus_get_param(NULL
,
1021 "DoSRefuseSingleHopClientRendezvous",
1022 0 /* default */, 0, 1);
1025 /* Log a heartbeat message with some statistics. */
1027 dos_log_heartbeat(void)
1029 smartlist_t
*elems
= smartlist_new();
1031 /* Stats number coming from relay.c append_cell_to_circuit_queue(). */
1032 smartlist_add_asprintf(elems
,
1033 "%" PRIu64
" circuits killed with too many cells",
1034 stats_n_circ_max_cell_reached
);
1036 if (dos_cc_enabled
) {
1037 smartlist_add_asprintf(elems
,
1038 "%" PRIu64
" circuits rejected, "
1039 "%" PRIu32
" marked addresses, "
1040 "%" PRIu32
" marked addresses for max queue",
1041 cc_num_rejected_cells
, cc_num_marked_addrs
,
1042 cc_num_marked_addrs_max_queue
);
1044 smartlist_add_asprintf(elems
, "[DoSCircuitCreationEnabled disabled]");
1047 if (dos_conn_enabled
) {
1048 smartlist_add_asprintf(elems
,
1049 "%" PRIu64
" same address concurrent "
1050 "connections rejected", conn_num_addr_rejected
);
1051 smartlist_add_asprintf(elems
,
1052 "%" PRIu64
" connections rejected",
1053 conn_num_addr_connect_rejected
);
1055 smartlist_add_asprintf(elems
, "[DoSConnectionEnabled disabled]");
1058 if (dos_should_refuse_single_hop_client()) {
1059 smartlist_add_asprintf(elems
,
1060 "%" PRIu64
" single hop clients refused",
1061 num_single_hop_client_refused
);
1063 smartlist_add_asprintf(elems
,
1064 "[DoSRefuseSingleHopClientRendezvous disabled]");
1067 if (dos_stream_enabled
) {
1068 smartlist_add_asprintf(elems
,
1069 "%" PRIu64
" stream rejected",
1070 stream_num_rejected
);
1072 smartlist_add_asprintf(elems
, "[DoSStreamCreationEnabled disabled]");
1076 smartlist_add_asprintf(elems
,
1077 "%" PRIu64
" INTRODUCE2 rejected",
1078 hs_dos_get_intro2_rejected_count());
1080 char *msg
= smartlist_join_strings(elems
, ", ", 0, NULL
);
1082 log_notice(LD_HEARTBEAT
,
1083 "Heartbeat: DoS mitigation since startup: %s.", msg
);
1086 SMARTLIST_FOREACH(elems
, char *, e
, tor_free(e
));
1087 smartlist_free(elems
);
1090 /* Called when a new client connection has been established on the given
1093 dos_new_client_conn(or_connection_t
*or_conn
, const char *transport_name
)
1095 clientmap_entry_t
*entry
;
1097 tor_assert(or_conn
);
1098 tor_assert_nonfatal(!or_conn
->tracked_for_dos_mitigation
);
1100 /* Past that point, we know we have at least one DoS detection subsystem
1101 * enabled so we'll start allocating stuff. */
1102 if (!dos_is_enabled()) {
1106 /* We are only interested in client connection from the geoip cache. */
1107 entry
= geoip_lookup_client(&TO_CONN(or_conn
)->addr
, transport_name
,
1108 GEOIP_CLIENT_CONNECT
);
1109 if (BUG(entry
== NULL
)) {
1110 /* Should never happen because we note down the address in the geoip
1111 * cache before this is called. */
1115 /* Update stats from this new connect. */
1116 conn_update_on_connect(&entry
->dos_stats
.conn_stats
,
1117 &TO_CONN(or_conn
)->addr
);
1119 or_conn
->tracked_for_dos_mitigation
= 1;
1125 /* Called when a client connection for the given IP address has been closed. */
1127 dos_close_client_conn(const or_connection_t
*or_conn
)
1129 clientmap_entry_t
*entry
;
1131 tor_assert(or_conn
);
1133 /* We have to decrement the count on tracked connection only even if the
1134 * subsystem has been disabled at runtime because it might be re-enabled
1135 * after and we need to keep a synchronized counter at all time. */
1136 if (!or_conn
->tracked_for_dos_mitigation
) {
1140 /* We are only interested in client connection from the geoip cache. */
1141 entry
= geoip_lookup_client(&TO_CONN(or_conn
)->addr
, NULL
,
1142 GEOIP_CLIENT_CONNECT
);
1143 if (entry
== NULL
) {
1144 /* This can happen because we can close a connection before the channel
1145 * got to be noted down in the geoip cache. */
1149 /* Update stats from this new close. */
1150 conn_update_on_close(&entry
->dos_stats
.conn_stats
, &TO_CONN(or_conn
)->addr
);
1156 /* Called when the consensus has changed. We might have new consensus
1157 * parameters to look at. */
1159 dos_consensus_has_changed(const networkstatus_t
*ns
)
1161 /* There are two ways to configure this subsystem, one at startup through
1162 * dos_init() which is called when the options are parsed. And this one
1163 * through the consensus. We don't want to enable any DoS mitigation if we
1164 * aren't a public relay. */
1165 if (!public_server_mode(get_options())) {
1169 cc_consensus_has_changed(ns
);
1170 conn_consensus_has_changed(ns
);
1172 /* We were already enabled or we just became enabled but either way, set the
1173 * consensus parameters for all subsystems. */
1174 set_dos_parameters(ns
);
1177 /* Return true iff the DoS mitigation subsystem is enabled. */
1181 return dos_is_enabled();
1184 /* Free everything from the Denial of Service subsystem. */
1188 /* Free the circuit creation mitigation subsystem. It is safe to do this
1189 * even if it wasn't initialized. */
1192 /* Free the connection mitigation subsystem. It is safe to do this even if
1193 * it wasn't initialized. */
1197 /* Initialize the Denial of Service subsystem. */
1201 /* To initialize, we only need to get the parameters. */
1202 set_dos_parameters(NULL
);