dos.c (40706B)
1 /* Copyright (c) 2018-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /* 5 * \file dos.c 6 * \brief Implement Denial of Service mitigation subsystem. 7 */ 8 9 #define DOS_PRIVATE 10 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" 25 26 #include "core/or/dos.h" 27 #include "core/or/dos_sys.h" 28 29 #include "core/or/dos_options_st.h" 30 #include "core/or/or_connection_st.h" 31 32 /* 33 * Circuit creation denial of service mitigation. 34 * 35 * Namespace used for this mitigation framework is "dos_cc_" where "cc" is for 36 * Circuit Creation. 37 */ 38 39 /* Is the circuit creation DoS mitigation enabled? */ 40 static unsigned int dos_cc_enabled = 0; 41 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; 49 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; 54 55 /* 56 * Concurrent connection denial of service mitigation. 57 * 58 * Namespace used for this mitigation framework is "dos_conn_". 59 */ 60 61 /* Is the connection DoS mitigation enabled? */ 62 static unsigned int dos_conn_enabled = 0; 63 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; 72 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; 76 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; 80 81 /* 82 * Stream denial of service mitigation. 83 * 84 * Namespace used for this mitigation framework is "dos_stream_". 85 */ 86 87 /* Is the connection DoS mitigation enabled? */ 88 static unsigned int dos_stream_enabled = 0; 89 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; 95 96 /* Keep some stats for the heartbeat so we can report out. */ 97 static uint64_t stream_num_rejected; 98 99 /* 100 * General interface of the denial of service mitigation subsystem. 101 */ 102 103 /* Keep stats for the heartbeat. */ 104 static uint64_t num_single_hop_client_refused; 105 106 /** Return the consensus parameter for the outbound circ_max_cell_queue_size 107 * limit. */ 108 static uint32_t 109 get_param_dos_num_circ_max_outq(const networkstatus_t *ns) 110 { 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 114 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); 120 } 121 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)) 126 { 127 if (dos_get_options()->DoSCircuitCreationEnabled != -1) { 128 return dos_get_options()->DoSCircuitCreationEnabled; 129 } 130 131 return !!networkstatus_get_param(ns, "DoSCircuitCreationEnabled", 132 DOS_CC_ENABLED_DEFAULT, 0, 1); 133 } 134 135 /* Return the parameter for the minimum concurrent connection at which we'll 136 * start counting circuit for a specific client address. */ 137 STATIC uint32_t 138 get_param_cc_min_concurrent_connection(const networkstatus_t *ns) 139 { 140 if (dos_get_options()->DoSCircuitCreationMinConnections) { 141 return dos_get_options()->DoSCircuitCreationMinConnections; 142 } 143 return networkstatus_get_param(ns, "DoSCircuitCreationMinConnections", 144 DOS_CC_MIN_CONCURRENT_CONN_DEFAULT, 145 1, INT32_MAX); 146 } 147 148 /* Return the parameter for the time rate that is how many circuits over this 149 * time span. */ 150 static uint32_t 151 get_param_cc_circuit_rate(const networkstatus_t *ns) 152 { 153 /* This is in seconds. */ 154 if (dos_get_options()->DoSCircuitCreationRate) { 155 return dos_get_options()->DoSCircuitCreationRate; 156 } 157 return networkstatus_get_param(ns, "DoSCircuitCreationRate", 158 DOS_CC_CIRCUIT_RATE_DEFAULT, 159 1, INT32_MAX); 160 } 161 162 /* Return the parameter for the maximum circuit count for the circuit time 163 * rate. */ 164 STATIC uint32_t 165 get_param_cc_circuit_burst(const networkstatus_t *ns) 166 { 167 if (dos_get_options()->DoSCircuitCreationBurst) { 168 return dos_get_options()->DoSCircuitCreationBurst; 169 } 170 return networkstatus_get_param(ns, "DoSCircuitCreationBurst", 171 DOS_CC_CIRCUIT_BURST_DEFAULT, 172 1, INT32_MAX); 173 } 174 175 /* Return the consensus parameter of the circuit creation defense type. */ 176 static uint32_t 177 get_param_cc_defense_type(const networkstatus_t *ns) 178 { 179 if (dos_get_options()->DoSCircuitCreationDefenseType) { 180 return dos_get_options()->DoSCircuitCreationDefenseType; 181 } 182 return networkstatus_get_param(ns, "DoSCircuitCreationDefenseType", 183 DOS_CC_DEFENSE_TYPE_DEFAULT, 184 DOS_CC_DEFENSE_NONE, DOS_CC_DEFENSE_MAX); 185 } 186 187 /* Return the consensus parameter of the defense time period which is how much 188 * time should we defend against a malicious client address. */ 189 static int32_t 190 get_param_cc_defense_time_period(const networkstatus_t *ns) 191 { 192 /* Time in seconds. */ 193 if (dos_get_options()->DoSCircuitCreationDefenseTimePeriod) { 194 return dos_get_options()->DoSCircuitCreationDefenseTimePeriod; 195 } 196 return networkstatus_get_param(ns, "DoSCircuitCreationDefenseTimePeriod", 197 DOS_CC_DEFENSE_TIME_PERIOD_DEFAULT, 198 0, INT32_MAX); 199 } 200 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)) 205 { 206 if (dos_get_options()->DoSConnectionEnabled != -1) { 207 return dos_get_options()->DoSConnectionEnabled; 208 } 209 return !!networkstatus_get_param(ns, "DoSConnectionEnabled", 210 DOS_CONN_ENABLED_DEFAULT, 0, 1); 211 } 212 213 /* Return the consensus parameter for the maximum concurrent connection 214 * allowed. */ 215 STATIC uint32_t 216 get_param_conn_max_concurrent_count(const networkstatus_t *ns) 217 { 218 if (dos_get_options()->DoSConnectionMaxConcurrentCount) { 219 return dos_get_options()->DoSConnectionMaxConcurrentCount; 220 } 221 return networkstatus_get_param(ns, "DoSConnectionMaxConcurrentCount", 222 DOS_CONN_MAX_CONCURRENT_COUNT_DEFAULT, 223 1, INT32_MAX); 224 } 225 226 /* Return the consensus parameter of the connection defense type. */ 227 static uint32_t 228 get_param_conn_defense_type(const networkstatus_t *ns) 229 { 230 if (dos_get_options()->DoSConnectionDefenseType) { 231 return dos_get_options()->DoSConnectionDefenseType; 232 } 233 return networkstatus_get_param(ns, "DoSConnectionDefenseType", 234 DOS_CONN_DEFENSE_TYPE_DEFAULT, 235 DOS_CONN_DEFENSE_NONE, DOS_CONN_DEFENSE_MAX); 236 } 237 238 /* Return the connection connect rate parameters either from the configuration 239 * file or, if not found, consensus parameter. */ 240 static uint32_t 241 get_param_conn_connect_rate(const networkstatus_t *ns) 242 { 243 if (dos_get_options()->DoSConnectionConnectRate) { 244 return dos_get_options()->DoSConnectionConnectRate; 245 } 246 return networkstatus_get_param(ns, "DoSConnectionConnectRate", 247 DOS_CONN_CONNECT_RATE_DEFAULT, 248 1, INT32_MAX); 249 } 250 251 /* Return the connection connect burst parameters either from the 252 * configuration file or, if not found, consensus parameter. */ 253 STATIC uint32_t 254 get_param_conn_connect_burst(const networkstatus_t *ns) 255 { 256 if (dos_get_options()->DoSConnectionConnectBurst) { 257 return dos_get_options()->DoSConnectionConnectBurst; 258 } 259 return networkstatus_get_param(ns, "DoSConnectionConnectBurst", 260 DOS_CONN_CONNECT_BURST_DEFAULT, 261 1, INT32_MAX); 262 } 263 264 /* Return the connection connect defense time period from the configuration 265 * file or, if not found, the consensus parameter. */ 266 static int32_t 267 get_param_conn_connect_defense_time_period(const networkstatus_t *ns) 268 { 269 /* Time in seconds. */ 270 if (dos_get_options()->DoSConnectionConnectDefenseTimePeriod) { 271 return dos_get_options()->DoSConnectionConnectDefenseTimePeriod; 272 } 273 return networkstatus_get_param(ns, "DoSConnectionConnectDefenseTimePeriod", 274 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_DEFAULT, 275 DOS_CONN_CONNECT_DEFENSE_TIME_PERIOD_MIN, 276 INT32_MAX); 277 } 278 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)) 283 { 284 if (dos_get_options()->DoSStreamCreationEnabled != -1) { 285 return dos_get_options()->DoSStreamCreationEnabled; 286 } 287 288 return !!networkstatus_get_param(ns, "DoSStreamCreationEnabled", 289 DOS_STREAM_ENABLED_DEFAULT, 0, 1); 290 } 291 292 /* Return the parameter for the time rate that is how many stream per circuit 293 * over this time span. */ 294 static uint32_t 295 get_param_stream_rate(const networkstatus_t *ns) 296 { 297 /* This is in seconds. */ 298 if (dos_get_options()->DoSStreamCreationRate) { 299 return dos_get_options()->DoSStreamCreationRate; 300 } 301 return networkstatus_get_param(ns, "DoSStreamCreationRate", 302 DOS_STREAM_RATE_DEFAULT, 303 1, INT32_MAX); 304 } 305 306 /* Return the parameter for the maximum circuit count for the circuit time 307 * rate. */ 308 static uint32_t 309 get_param_stream_burst(const networkstatus_t *ns) 310 { 311 if (dos_get_options()->DoSStreamCreationBurst) { 312 return dos_get_options()->DoSStreamCreationBurst; 313 } 314 return networkstatus_get_param(ns, "DoSStreamCreationBurst", 315 DOS_STREAM_BURST_DEFAULT, 316 1, INT32_MAX); 317 } 318 319 /* Return the consensus parameter of the circuit creation defense type. */ 320 static uint32_t 321 get_param_stream_defense_type(const networkstatus_t *ns) 322 { 323 if (dos_get_options()->DoSStreamCreationDefenseType) { 324 return dos_get_options()->DoSStreamCreationDefenseType; 325 } 326 return networkstatus_get_param(ns, "DoSStreamCreationDefenseType", 327 DOS_STREAM_DEFENSE_TYPE_DEFAULT, 328 DOS_STREAM_DEFENSE_NONE, 329 DOS_STREAM_DEFENSE_MAX); 330 } 331 332 /* Set circuit creation parameters located in the consensus or their default 333 * if none are present. Called at initialization or when the consensus 334 * changes. */ 335 static void 336 set_dos_parameters(const networkstatus_t *ns) 337 { 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); 345 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); 354 355 /* Circuit. */ 356 dos_num_circ_max_outq = get_param_dos_num_circ_max_outq(ns); 357 358 /* Stream. */ 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); 363 } 364 365 /* Free everything for the circuit creation DoS mitigation subsystem. */ 366 static void 367 cc_free_all(void) 368 { 369 /* If everything is freed, the circuit creation subsystem is not enabled. */ 370 dos_cc_enabled = 0; 371 } 372 373 /* Called when the consensus has changed. Do appropriate actions for the 374 * circuit creation subsystem. */ 375 static void 376 cc_consensus_has_changed(const networkstatus_t *ns) 377 { 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)) { 381 cc_free_all(); 382 } 383 } 384 385 /** Return the number of circuits we allow per second under the current 386 * configuration. */ 387 STATIC uint64_t 388 get_circuit_rate_per_second(void) 389 { 390 return dos_cc_circuit_rate; 391 } 392 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. */ 396 STATIC void 397 cc_stats_refill_bucket(cc_client_stats_t *stats, const tor_addr_t *addr) 398 { 399 uint32_t new_circuit_bucket_count; 400 uint64_t num_token, elapsed_time_last_refill = 0, circuit_rate = 0; 401 time_t now; 402 int64_t last_refill_ts; 403 404 tor_assert(stats); 405 tor_assert(addr); 406 407 now = approx_time(); 408 last_refill_ts = (int64_t)stats->last_circ_bucket_refill_ts; 409 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) { 415 goto done; 416 } 417 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 420 * per second. */ 421 circuit_rate = get_circuit_rate_per_second(); 422 423 /* We've never filled the bucket so fill it with the maximum being the burst 424 * and we are done. 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; 429 goto end; 430 } 431 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 439 * rare situation.*/ 440 if ((int64_t)now < last_refill_ts) { 441 /* Use the maximum allowed value of token. */ 442 num_token = dos_cc_circuit_burst; 443 goto end; 444 } 445 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; 450 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; 455 goto end; 456 } 457 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; 462 463 end: 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; 467 } else { 468 /* We cap the bucket to the burst value else this could overflow uint32_t 469 * over time. */ 470 new_circuit_bucket_count = MIN(stats->circuit_bucket + (uint32_t)num_token, 471 dos_cc_circuit_burst); 472 } 473 474 /* This function is not allowed to make the bucket count larger than the 475 * burst value */ 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); 482 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); 488 489 stats->circuit_bucket = new_circuit_bucket_count; 490 stats->last_circ_bucket_refill_ts = now; 491 492 done: 493 return; 494 } 495 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. */ 499 static int 500 cc_has_exhausted_circuits(const dos_client_stats_t *stats) 501 { 502 tor_assert(stats); 503 return stats->cc_stats.circuit_bucket == 0 && 504 stats->conn_stats.concurrent_count >= dos_cc_min_concurrent_conn; 505 } 506 507 /* Mark client address by setting a timestamp in the stats object which tells 508 * us until when it is marked as positively detected. */ 509 static void 510 cc_mark_client(cc_client_stats_t *stats) 511 { 512 tor_assert(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); 518 } 519 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. */ 523 static int 524 cc_channel_addr_is_marked(channel_t *chan) 525 { 526 time_t now; 527 tor_addr_t addr; 528 clientmap_entry_t *entry; 529 cc_client_stats_t *stats = NULL; 530 531 if (chan == NULL) { 532 goto end; 533 } 534 /* Must be a client connection else we ignore. */ 535 if (!channel_is_client(chan)) { 536 goto end; 537 } 538 /* Without an IP address, nothing can work. */ 539 if (!channel_get_addr_if_possible(chan, &addr)) { 540 goto end; 541 } 542 543 /* We are only interested in client connection from the geoip cache. */ 544 entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT); 545 if (entry == NULL) { 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. */ 549 goto end; 550 } 551 now = approx_time(); 552 stats = &entry->dos_stats.cc_stats; 553 554 end: 555 return stats && stats->marked_until_ts >= now; 556 } 557 558 /* Concurrent connection private API. */ 559 560 /* Mark client connection stats by setting a timestamp which tells us until 561 * when it is marked as positively detected. */ 562 static void 563 conn_mark_client(conn_client_stats_t *stats) 564 { 565 tor_assert(stats); 566 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); 572 } 573 574 /* Free everything for the connection DoS mitigation subsystem. */ 575 static void 576 conn_free_all(void) 577 { 578 dos_conn_enabled = 0; 579 } 580 581 /* Called when the consensus has changed. Do appropriate actions for the 582 * connection mitigation subsystem. */ 583 static void 584 conn_consensus_has_changed(const networkstatus_t *ns) 585 { 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)) { 589 conn_free_all(); 590 } 591 } 592 593 /** Called when a new client connection has arrived. The following will update 594 * the client connection statistics. 595 * 596 * The addr is used for logging purposes only. 597 * 598 * If the connect counter reaches its limit, it is marked. */ 599 static void 600 conn_update_on_connect(conn_client_stats_t *stats, const tor_addr_t *addr) 601 { 602 tor_assert(stats); 603 tor_assert(addr); 604 605 /* Update concurrent count for this new connect. */ 606 stats->concurrent_count++; 607 608 /* Refill connect connection count. */ 609 token_bucket_ctr_refill(&stats->connect_count, 610 (uint32_t) monotime_coarse_absolute_sec()); 611 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); 615 } 616 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); 623 } 624 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)); 629 } 630 631 /** Called when a client connection is closed. The following will update 632 * the client connection statistics. 633 * 634 * The addr is used for logging purposes only. */ 635 static void 636 conn_update_on_close(conn_client_stats_t *stats, const tor_addr_t *addr) 637 { 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)) { 642 return; 643 } 644 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); 649 } 650 651 /* General private API */ 652 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. */ 655 static inline int 656 dos_is_enabled(void) 657 { 658 return (dos_cc_enabled || dos_conn_enabled); 659 } 660 661 /* Circuit creation public API. */ 662 663 /** Return the number of rejected circuits. */ 664 uint64_t 665 dos_get_num_cc_rejected(void) 666 { 667 return cc_num_rejected_cells; 668 } 669 670 /** Return the number of marked addresses. */ 671 uint32_t 672 dos_get_num_cc_marked_addr(void) 673 { 674 return cc_num_marked_addrs; 675 } 676 677 /** Return the number of marked addresses due to max queue limit reached. */ 678 uint32_t 679 dos_get_num_cc_marked_addr_maxq(void) 680 { 681 return cc_num_marked_addrs_max_queue; 682 } 683 684 /** Return number of concurrent connections rejected. */ 685 uint64_t 686 dos_get_num_conn_addr_rejected(void) 687 { 688 return conn_num_addr_rejected; 689 } 690 691 /** Return the number of connection rejected. */ 692 uint64_t 693 dos_get_num_conn_addr_connect_rejected(void) 694 { 695 return conn_num_addr_connect_rejected; 696 } 697 698 /** Return the number of single hop refused. */ 699 uint64_t 700 dos_get_num_single_hop_refused(void) 701 { 702 return num_single_hop_client_refused; 703 } 704 705 /* Called when a CREATE cell is received from the given channel. */ 706 void 707 dos_cc_new_create_cell(channel_t *chan) 708 { 709 tor_addr_t addr; 710 clientmap_entry_t *entry; 711 712 tor_assert(chan); 713 714 /* Skip everything if not enabled. */ 715 if (!dos_cc_enabled) { 716 goto end; 717 } 718 719 /* Must be a client connection else we ignore. */ 720 if (!channel_is_client(chan)) { 721 goto end; 722 } 723 /* Without an IP address, nothing can work. */ 724 if (!channel_get_addr_if_possible(chan, &addr)) { 725 goto end; 726 } 727 728 /* We are only interested in client connection from the geoip cache. */ 729 entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT); 730 if (entry == NULL) { 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. */ 734 goto end; 735 } 736 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. */ 741 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); 745 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--; 750 } 751 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 757 * lots of logs. */ 758 if (entry->dos_stats.cc_stats.marked_until_ts == 0) { 759 log_debug(LD_DOS, "Detected circuit creation DoS by address: %s", 760 fmt_addr(&addr)); 761 cc_num_marked_addrs++; 762 } 763 cc_mark_client(&entry->dos_stats.cc_stats); 764 } 765 766 end: 767 return; 768 } 769 770 /* Return the defense type that should be used for this circuit. 771 * 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) 775 { 776 tor_assert(chan); 777 778 /* Skip everything if not enabled. */ 779 if (!dos_cc_enabled) { 780 goto end; 781 } 782 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; 790 } 791 792 end: 793 return DOS_CC_DEFENSE_NONE; 794 } 795 796 /* Concurrent connection detection public API. */ 797 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) 802 { 803 clientmap_entry_t *entry; 804 805 tor_assert(addr); 806 807 /* Skip everything if not enabled. */ 808 if (!dos_conn_enabled) { 809 goto end; 810 } 811 812 /* We are only interested in client connection from the geoip cache. */ 813 entry = geoip_lookup_client(addr, NULL, GEOIP_CLIENT_CONNECT); 814 if (entry == NULL) { 815 goto end; 816 } 817 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; 822 } 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; 827 828 /* Need to be above the maximum concurrent connection count to trigger a 829 * defense. */ 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; 834 } 835 836 end: 837 return DOS_CONN_DEFENSE_NONE; 838 } 839 840 /* Stream creation public API. */ 841 842 /** Return the number of rejected stream and resolve. */ 843 uint64_t 844 dos_get_num_stream_rejected(void) 845 { 846 return stream_num_rejected; 847 } 848 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 852 * limit. */ 853 dos_stream_defense_type_t 854 dos_stream_new_begin_or_resolve_cell(or_circuit_t *circ) 855 { 856 if (!dos_stream_enabled || circ == NULL) 857 return DOS_STREAM_DEFENSE_NONE; 858 859 token_bucket_ctr_refill(&circ->stream_limiter, 860 (uint32_t) monotime_coarse_absolute_sec()); 861 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; 865 } 866 /* if defense type is DOS_STREAM_DEFENSE_NONE but DoSStreamEnabled is true, 867 * we count offending cells as rejected, despite them being actually 868 * accepted. */ 869 ++stream_num_rejected; 870 return dos_stream_defense_type; 871 } 872 873 /* Initialize the token bucket for stream rate limit on a circuit. */ 874 void 875 dos_stream_init_circ_tbf(or_circuit_t *circ) 876 { 877 token_bucket_ctr_init(&circ->stream_limiter, dos_stream_rate, 878 dos_stream_burst, 879 (uint32_t) monotime_coarse_absolute_sec()); 880 } 881 882 /* General API */ 883 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. 886 * 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. */ 891 void 892 dos_geoip_entry_about_to_free(const clientmap_entry_t *geoip_ent) 893 { 894 tor_assert(geoip_ent); 895 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) { 899 goto end; 900 } 901 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, 909 CMP_EXACT)) { 910 or_conn->tracked_for_dos_mitigation = 0; 911 } 912 } 913 } SMARTLIST_FOREACH_END(conn); 914 915 end: 916 return; 917 } 918 919 /** A new geoip client entry has been allocated, initialize its DoS object. */ 920 void 921 dos_geoip_entry_init(clientmap_entry_t *geoip_ent) 922 { 923 tor_assert(geoip_ent); 924 925 /* Initialize the connection count counter with the rate and burst 926 * parameters taken either from configuration or consensus. 927 * 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()); 933 } 934 935 /** Note that the given channel has sent outbound the maximum amount of cell 936 * allowed on the next channel. */ 937 void 938 dos_note_circ_max_outq(const channel_t *chan) 939 { 940 tor_addr_t addr; 941 clientmap_entry_t *entry; 942 943 tor_assert(chan); 944 945 /* Skip everything if circuit creation defense is disabled. */ 946 if (!dos_cc_enabled) { 947 goto end; 948 } 949 950 /* Must be a client connection else we ignore. */ 951 if (!channel_is_client(chan)) { 952 goto end; 953 } 954 /* Without an IP address, nothing can work. */ 955 if (!channel_get_addr_if_possible(chan, &addr)) { 956 goto end; 957 } 958 959 /* We are only interested in client connection from the geoip cache. */ 960 entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT); 961 if (entry == NULL) { 962 goto end; 963 } 964 965 /* Is the client marked? If yes, just ignore. */ 966 if (entry->dos_stats.cc_stats.marked_until_ts >= approx_time()) { 967 goto end; 968 } 969 970 /* If max outq parameter is 0, it means disabled, just ignore. */ 971 if (dos_num_circ_max_outq == 0) { 972 goto end; 973 } 974 975 entry->dos_stats.num_circ_max_cell_queue_size++; 976 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++; 985 } 986 log_info(LD_DOS, "Detected outbound max circuit queue from addr: %s", 987 fmt_addr(&addr)); 988 cc_mark_client(&entry->dos_stats.cc_stats); 989 990 /* Reset after being marked so once unmarked, we start back clean. */ 991 entry->dos_stats.num_circ_max_cell_queue_size = 0; 992 } 993 994 end: 995 return; 996 } 997 998 /* Note down that we've just refused a single hop client. This increments a 999 * counter later used for the heartbeat. */ 1000 void 1001 dos_note_refuse_single_hop_client(void) 1002 { 1003 num_single_hop_client_refused++; 1004 } 1005 1006 /* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should 1007 * be refused. */ 1008 int 1009 dos_should_refuse_single_hop_client(void) 1010 { 1011 /* If we aren't a public relay, this shouldn't apply to anything. */ 1012 if (!public_server_mode(get_options())) { 1013 return 0; 1014 } 1015 1016 if (dos_get_options()->DoSRefuseSingleHopClientRendezvous != -1) { 1017 return dos_get_options()->DoSRefuseSingleHopClientRendezvous; 1018 } 1019 1020 return (int) networkstatus_get_param(NULL, 1021 "DoSRefuseSingleHopClientRendezvous", 1022 0 /* default */, 0, 1); 1023 } 1024 1025 /* Log a heartbeat message with some statistics. */ 1026 void 1027 dos_log_heartbeat(void) 1028 { 1029 smartlist_t *elems = smartlist_new(); 1030 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); 1035 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); 1043 } else { 1044 smartlist_add_asprintf(elems, "[DoSCircuitCreationEnabled disabled]"); 1045 } 1046 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); 1054 } else { 1055 smartlist_add_asprintf(elems, "[DoSConnectionEnabled disabled]"); 1056 } 1057 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); 1062 } else { 1063 smartlist_add_asprintf(elems, 1064 "[DoSRefuseSingleHopClientRendezvous disabled]"); 1065 } 1066 1067 if (dos_stream_enabled) { 1068 smartlist_add_asprintf(elems, 1069 "%" PRIu64 " stream rejected", 1070 stream_num_rejected); 1071 } else { 1072 smartlist_add_asprintf(elems, "[DoSStreamCreationEnabled disabled]"); 1073 } 1074 1075 /* HS DoS stats. */ 1076 smartlist_add_asprintf(elems, 1077 "%" PRIu64 " INTRODUCE2 rejected", 1078 hs_dos_get_intro2_rejected_count()); 1079 1080 char *msg = smartlist_join_strings(elems, ", ", 0, NULL); 1081 1082 log_notice(LD_HEARTBEAT, 1083 "Heartbeat: DoS mitigation since startup: %s.", msg); 1084 1085 tor_free(msg); 1086 SMARTLIST_FOREACH(elems, char *, e, tor_free(e)); 1087 smartlist_free(elems); 1088 } 1089 1090 /* Called when a new client connection has been established on the given 1091 * address. */ 1092 void 1093 dos_new_client_conn(or_connection_t *or_conn, const char *transport_name) 1094 { 1095 clientmap_entry_t *entry; 1096 1097 tor_assert(or_conn); 1098 tor_assert_nonfatal(!or_conn->tracked_for_dos_mitigation); 1099 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()) { 1103 goto end; 1104 } 1105 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. */ 1112 goto end; 1113 } 1114 1115 /* Update stats from this new connect. */ 1116 conn_update_on_connect(&entry->dos_stats.conn_stats, 1117 &TO_CONN(or_conn)->addr); 1118 1119 or_conn->tracked_for_dos_mitigation = 1; 1120 1121 end: 1122 return; 1123 } 1124 1125 /* Called when a client connection for the given IP address has been closed. */ 1126 void 1127 dos_close_client_conn(const or_connection_t *or_conn) 1128 { 1129 clientmap_entry_t *entry; 1130 1131 tor_assert(or_conn); 1132 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) { 1137 goto end; 1138 } 1139 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. */ 1146 goto end; 1147 } 1148 1149 /* Update stats from this new close. */ 1150 conn_update_on_close(&entry->dos_stats.conn_stats, &TO_CONN(or_conn)->addr); 1151 1152 end: 1153 return; 1154 } 1155 1156 /* Called when the consensus has changed. We might have new consensus 1157 * parameters to look at. */ 1158 void 1159 dos_consensus_has_changed(const networkstatus_t *ns) 1160 { 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())) { 1166 return; 1167 } 1168 1169 cc_consensus_has_changed(ns); 1170 conn_consensus_has_changed(ns); 1171 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); 1175 } 1176 1177 /* Return true iff the DoS mitigation subsystem is enabled. */ 1178 int 1179 dos_enabled(void) 1180 { 1181 return dos_is_enabled(); 1182 } 1183 1184 /* Free everything from the Denial of Service subsystem. */ 1185 void 1186 dos_free_all(void) 1187 { 1188 /* Free the circuit creation mitigation subsystem. It is safe to do this 1189 * even if it wasn't initialized. */ 1190 cc_free_all(); 1191 1192 /* Free the connection mitigation subsystem. It is safe to do this even if 1193 * it wasn't initialized. */ 1194 conn_free_all(); 1195 } 1196 1197 /* Initialize the Denial of Service subsystem. */ 1198 void 1199 dos_init(void) 1200 { 1201 /* To initialize, we only need to get the parameters. */ 1202 set_dos_parameters(NULL); 1203 }