[tor/master] Merge branch 'ticket24902_029_05' into ticket24902_033_02

commit cd81403cc0d73d53cb7f3650b38d49c54100af25 Merge: 03ab24b44 9aca7d473 Author: David Goulet <dgoulet@torproject.org> Date: Tue Jan 30 09:33:12 2018 -0500 Merge branch 'ticket24902_029_05' into ticket24902_033_02 changes/ticket24902 | 13 + doc/tor.1.txt | 88 ++++++ src/common/log.c | 2 +- src/common/torlog.h | 4 +- src/or/channel.c | 9 +- src/or/channel.h | 3 +- src/or/command.c | 13 + src/or/config.c | 25 ++ src/or/connection.c | 16 ++ src/or/dos.c | 737 +++++++++++++++++++++++++++++++++++++++++++++++++ src/or/dos.h | 140 ++++++++++ src/or/geoip.c | 63 +++-- src/or/geoip.h | 27 ++ src/or/include.am | 2 + src/or/main.c | 2 + src/or/networkstatus.c | 2 + src/or/or.h | 33 +++ src/or/rendmid.c | 12 + src/or/status.c | 2 + src/test/include.am | 1 + src/test/test.c | 1 + src/test/test.h | 1 + src/test/test_dos.c | 248 +++++++++++++++++ 23 files changed, 1410 insertions(+), 34 deletions(-) diff --cc doc/tor.1.txt index ef3d1eb9e,58997cdf3..5ad818365 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@@ -2749,9 -2438,97 +2749,97 @@@ The following options are used to confi non-anonymous HiddenServiceSingleHopMode. Enables direct connections in the server-side hidden service protocol. If you are using this option, you need to disable all client-side services on your Tor instance, - including setting SOCKSPort to "0". - (Default: 0) + including setting SOCKSPort to "0". Can not be changed while tor is + running. (Default: 0) + DENIAL OF SERVICE MITIGATION OPTIONS + ------------------------------------ + + The following options are useful only for a public relay. They control the + Denial of Service mitigation subsystem. + + [[DoSCircuitCreationEnabled]] **DoSCircuitCreationEnabled** **0**|**1**|**auto**:: + + Enable circuit creation DoS mitigation. If enabled, tor will cache client + IPs along with statistics in order to detect circuit DoS attacks. If an + address is positively identified, tor will activate defenses against the + address. See the DoSCircuitCreationDefenseType option for more details. + This is a client to relay detection only. "auto" means use the consensus + parameter. + (Default: auto) + + [[DoSCircuitCreationMinConnections]] **DoSCircuitCreationMinConnections** __NUM__:: + + Minimum threshold of concurrent connections before a client address can be + flagged as executing a circuit creation DoS. In other words, once a client + address reaches the circuit rate and has a minimum of NUM concurrent + connections, a detection is positive. "0" means use the consensus + parameter. + (Default: 0) + + [[DoSCircuitCreationRate]] **DoSCircuitCreationRate** __NUM__:: + + The allowed circuit creation rate per second applied per client IP + address. If this option is 0, it obeys a consensus parameter. (Default: 0) + + [[DoSCircuitCreationBurst]] **DoSCircuitCreationBurst** __NUM__:: + + The allowed circuit creation burst per client IP address. If the circuit + rate and the burst are reached, a client is marked as executing a circuit + creation DoS. "0" means use the consensus parameter. + (Default: 0) + + [[DoSCircuitCreationDefenseType]] **DoSCircuitCreationDefenseType** __NUM__:: + + This is the type of defense applied to a detected client address. The + possible values are: + + 1: No defense. + 2: Refuse circuit creation for the DoSCircuitCreationDefenseTimePeriod period of time. + + + "0" means use the consensus parameter. + (Default: 0) + + [[DoSCircuitCreationDefenseTimePeriod]] **DoSCircuitCreationDefenseTimePeriod** __NUM__:: + + The base time period that the DoS defense is activated for. The actual + value is selected randomly for each activation from NUM+1 to 3/2 * NUM. + "0" means use the consensus parameter. + (Default: 0) + + [[DoSConnectionEnabled]] **DoSConnectionEnabled** **0**|**1**|**auto**:: + + Enable the connection DoS mitigation. For client address only, this allows + tor to mitigate against large number of concurrent connections made by a + single IP address. "auto" means use the consensus parameter. + (Default: auto) + + [[DoSConnectionMaxConcurrentCount]] **DoSConnectionMaxConcurrentCount** __NUM__:: + + The maximum threshold of concurrent connection from a client IP address. + Above this limit, a defense selected by DoSConnectionDefenseType is + applied. "0" means use the consensus parameter. + (Default: 0) + + [[DoSConnectionDefenseType]] **DoSConnectionDefenseType** __NUM__:: + + This is the type of defense applied to a detected client address for the + connection mitigation. The possible values are: + + 1: No defense. + 2: Immediately close new connections. + + + "0" means use the consensus parameter. + (Default: 0) + + [[DoSRefuseSingleHopClientRendezvous]] **DoSRefuseSingleHopClientRendezvous** **0**|**1**|**auto**:: + + Refuse establishment of rendezvous points for single hop clients. In other + words, if a client directly connects to the relay and sends an + ESTABLISH_RENDEZVOUS cell, it is silently dropped. "auto" means use the + consensus parameter. + (Default: auto) + TESTING NETWORK OPTIONS ----------------------- diff --cc src/common/log.c index ac6d07a92,4db1c9f0d..d59e5a403 --- a/src/common/log.c +++ b/src/common/log.c @@@ -1263,7 -1177,7 +1263,7 @@@ static const char *domain_list[] = "GENERAL", "CRYPTO", "NET", "CONFIG", "FS", "PROTOCOL", "MM", "HTTP", "APP", "CONTROL", "CIRC", "REND", "BUG", "DIR", "DIRSERV", "OR", "EDGE", "ACCT", "HIST", "HANDSHAKE", "HEARTBEAT", "CHANNEL", - "SCHED", "GUARD", "CONSDIFF", NULL - "SCHED", "DOS", NULL ++ "SCHED", "GUARD", "CONSDIFF", "DOS", NULL }; /** Return a bitmask for the log domain for which <b>domain</b> is the name, diff --cc src/common/torlog.h index b7d033adb,20b7d938f..cadfe3b87 --- a/src/common/torlog.h +++ b/src/common/torlog.h @@@ -99,12 -99,10 +99,14 @@@ #define LD_CHANNEL (1u<<21) /** Scheduler */ #define LD_SCHED (1u<<22) +/** Guard nodes */ +#define LD_GUARD (1u<<23) +/** Generation and application of consensus diffs. */ +#define LD_CONSDIFF (1u<<24) + /** Denial of Service mitigation. */ -#define LD_DOS (1u<<23) ++#define LD_DOS (1u<<25) /** Number of logging domains in the code. */ - #define N_LOGGING_DOMAINS 25 -#define N_LOGGING_DOMAINS 24 ++#define N_LOGGING_DOMAINS 26 /** This log message is not safe to send to a callback-based logger * immediately. Used as a flag, not a log domain. */ diff --cc src/or/channel.c index 345a90a00,54e10666d..094bf93e6 --- a/src/or/channel.c +++ b/src/or/channel.c @@@ -1885,9 -2570,20 +1885,10 @@@ channel_do_open_actions(channel_t *chan router_set_status(chan->identity_digest, 1); } else { /* only report it to the geoip module if it's not a known router */ - if (!router_get_by_id_digest(chan->identity_digest)) { + if (!connection_or_digest_is_known_relay(chan->identity_digest)) { 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; diff --cc src/or/config.c index afaf86785,3b4027433..f6875b7ed --- a/src/or/config.c +++ b/src/or/config.c @@@ -81,8 -29,8 +81,9 @@@ #include "dirserv.h" #include "dirvote.h" #include "dns.h" + #include "dos.h" #include "entrynodes.h" +#include "git_revision.h" #include "geoip.h" #include "hibernate.h" #include "main.h" @@@ -314,8 -240,21 +315,21 @@@ static config_var_t option_vars_[] = OBSOLETE("DisableIOCP"), OBSOLETE("DisableV2DirectoryInfo_"), OBSOLETE("DynamicDHGroups"), - VPORT(DNSPort, LINELIST, NULL), - V(DNSListenAddress, LINELIST, NULL), + VPORT(DNSPort), + OBSOLETE("DNSListenAddress"), + /* DoS circuit creation options. */ + V(DoSCircuitCreationEnabled, AUTOBOOL, "auto"), + V(DoSCircuitCreationMinConnections, UINT, "0"), + V(DoSCircuitCreationRate, UINT, "0"), + V(DoSCircuitCreationBurst, UINT, "0"), + V(DoSCircuitCreationDefenseType, INT, "0"), + V(DoSCircuitCreationDefenseTimePeriod, INTERVAL, "0"), + /* DoS connection options. */ + V(DoSConnectionEnabled, AUTOBOOL, "auto"), + V(DoSConnectionMaxConcurrentCount, UINT, "0"), + V(DoSConnectionDefenseType, INT, "0"), + /* DoS single hop client options. */ + V(DoSRefuseSingleHopClientRendezvous, AUTOBOOL, "auto"), V(DownloadExtraInfo, BOOL, "0"), V(TestingEnableConnBwEvent, BOOL, "0"), V(TestingEnableCellStatsEvent, BOOL, "0"), diff --cc src/or/connection.c index a020bef77,791fd95c2..5bbb61dfa --- a/src/or/connection.c +++ b/src/or/connection.c @@@ -702,9 -687,16 +703,16 @@@ connection_free_,(connection_t *conn) connection_ap_warn_and_unmark_if_pending_circ(TO_ENTRY_CONN(conn), "connection_free"); } -#endif +#endif /* 1 */ + + /* Notify the circuit creation DoS mitigation subsystem that an OR client + * connection has been closed. And only do that if we track it. */ + if (conn->type == CONN_TYPE_OR) { + dos_close_client_conn(TO_OR_CONN(conn)); + } + connection_unregister_events(conn); - connection_free_(conn); + connection_free_minimal(conn); } /** diff --cc src/or/geoip.h index acf61b97a,aa0fca50f..ccedc1bc1 --- a/src/or/geoip.h +++ b/src/or/geoip.h @@@ -19,7 -20,30 +20,30 @@@ STATIC int geoip_parse_entry(const cha STATIC int geoip_get_country_by_ipv4(uint32_t ipaddr); STATIC int geoip_get_country_by_ipv6(const struct in6_addr *addr); STATIC void clear_geoip_db(void); -#endif +#endif /* defined(GEOIP_PRIVATE) */ + + /** Entry in a map from IP address to the last time we've seen an incoming + * connection from that IP address. Used by bridges only to track which + * countries have them blocked, or the DoS mitigation subsystem if enabled. */ + typedef struct clientmap_entry_t { + HT_ENTRY(clientmap_entry_t) node; + tor_addr_t addr; + /* Name of pluggable transport used by this client. NULL if no + pluggable transport was used. */ + char *transport_name; + + /** Time when we last saw this IP address, in MINUTES since the epoch. + * + * (This will run out of space around 4011 CE. If Tor is still in use around + * 4000 CE, please remember to add more bits to last_seen_in_minutes.) */ + unsigned int last_seen_in_minutes:30; + unsigned int action:2; + + /* This object is used to keep some statistics per client address for the + * DoS mitigation subsystem. */ + dos_client_stats_t dos_stats; + } clientmap_entry_t; + int should_record_bridge_info(const or_options_t *options); int geoip_load_file(sa_family_t family, const char *filename); MOCK_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr)); diff --cc src/or/main.c index 10e606f3a,fcd8dc902..96c7e77c7 --- a/src/or/main.c +++ b/src/or/main.c @@@ -3483,9 -2990,7 +3484,10 @@@ tor_free_all(int postfork control_free_all(); sandbox_free_getaddrinfo_cache(); protover_free_all(); + bridges_free_all(); + consdiffmgr_free_all(); + hs_free_all(); + dos_free_all(); if (!postfork) { config_free_all(); or_state_free_all(); diff --cc src/or/networkstatus.c index aa0a8d15c,d9ae32560..77898445d --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@@ -51,8 -23,8 +51,9 @@@ #include "directory.h" #include "dirserv.h" #include "dirvote.h" + #include "dos.h" #include "entrynodes.h" +#include "hibernate.h" #include "main.h" #include "microdesc.h" #include "networkstatus.h" @@@ -1605,7 -1509,7 +1606,8 @@@ notify_networkstatus_changed(const netw const networkstatus_t *new_c) { notify_control_networkstatus_changed(old_c, new_c); + scheduler_notify_networkstatus_changed(old_c, new_c); + dos_consensus_has_changed(new_c); } /** Copy all the ancillary information (like router download status and so on) diff --cc src/or/or.h index c81e29c95,024a9cff0..0436533a9 --- a/src/or/or.h +++ b/src/or/or.h @@@ -4658,53 -4515,36 +4662,82 @@@ typedef struct /** If 1, we skip all OOS checks. */ int DisableOOSCheck; + /** Autobool: Should we include Ed25519 identities in extend2 cells? + * If -1, we should do whatever the consensus parameter says. */ + int ExtendByEd25519ID; + + /** Bool (default: 1): When testing routerinfos as a directory authority, + * do we enforce Ed25519 identity match? */ + /* NOTE: remove this option someday. */ + int AuthDirTestEd25519LinkKeys; + + /** Bool (default: 0): Tells if a %include was used on torrc */ + int IncludeUsed; + + /** The seconds after expiration which we as a relay should keep old + * consensuses around so that we can generate diffs from them. If 0, + * use the default. */ + int MaxConsensusAgeForDiffs; + + /** Bool (default: 0). Tells Tor to never try to exec another program. + */ + int NoExec; + + /** Have the KIST scheduler run every X milliseconds. If less than zero, do + * not use the KIST scheduler but use the old vanilla scheduler instead. If + * zero, do what the consensus says and fall back to using KIST as if this is + * set to "10 msec" if the consensus doesn't say anything. */ + int KISTSchedRunInterval; + + /** A multiplier for the KIST per-socket limit calculation. */ + double KISTSockBufSizeFactor; + + /** The list of scheduler type string ordered by priority that is first one + * has to be tried first. Default: KIST,KISTLite,Vanilla */ + smartlist_t *Schedulers; + /* An ordered list of scheduler_types mapped from Schedulers. */ + smartlist_t *SchedulerTypes_; + + /** List of files that were opened by %include in torrc and torrc-defaults */ + smartlist_t *FilesOpenedByIncludes; + + /** If true, Tor shouldn't install any posix signal handlers, since it is + * running embedded inside another process. + */ + int DisableSignalHandlers; ++ + /** Autobool: Is the circuit creation DoS mitigation subsystem enabled? */ + int DoSCircuitCreationEnabled; + /** Minimum concurrent connection needed from one single address before any + * defense is used. */ + int DoSCircuitCreationMinConnections; + /** Circuit rate used to refill the token bucket. */ + int DoSCircuitCreationRate; + /** Maximum allowed burst of circuits. Reaching that value, the address is + * detected as malicious and a defense might be used. */ + int DoSCircuitCreationBurst; + /** When an address is marked as malicous, what defense should be used + * against it. See the dos_cc_defense_type_t enum. */ + int DoSCircuitCreationDefenseType; + /** For how much time (in seconds) the defense is applicable for a malicious + * address. A random time delta is added to the defense time of an address + * which will be between 1 second and half of this value. */ + int DoSCircuitCreationDefenseTimePeriod; + + /** Autobool: Is the DoS connection mitigation subsystem enabled? */ + int DoSConnectionEnabled; + /** Maximum concurrent connection allowed per address. */ + int DoSConnectionMaxConcurrentCount; + /** When an address is reaches the maximum count, what defense should be + * used against it. See the dos_conn_defense_type_t enum. */ + int DoSConnectionDefenseType; + + /** Autobool: Do we refuse single hop client rendezvous? */ + int DoSRefuseSingleHopClientRendezvous; } or_options_t; +#define LOG_PROTOCOL_WARN (get_protocol_warning_severity_level()) + /** Persistent state for an onion router, as saved to disk. */ typedef struct { uint32_t magic_; diff --cc src/or/rendmid.c index 66d2f9311,441d5043c..c4a34ca62 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@@ -11,7 -12,7 +12,8 @@@ #include "circuitlist.h" #include "circuituse.h" #include "config.h" +#include "crypto.h" + #include "dos.h" #include "relay.h" #include "rendmid.h" #include "rephist.h" diff --cc src/or/status.c index 187dc4ad2,fa2238b9f..3b4c60585 --- a/src/or/status.c +++ b/src/or/status.c @@@ -27,8 -27,7 +27,9 @@@ #include "hibernate.h" #include "rephist.h" #include "statefile.h" +#include "hs_stats.h" +#include "hs_service.h" + #include "dos.h" static void log_accounting(const time_t now, const or_options_t *options); #include "geoip.h" diff --cc src/test/include.am index a4b9705fd,91b0a5910..9783f93d5 --- a/src/test/include.am +++ b/src/test/include.am @@@ -114,6 -92,6 +114,7 @@@ src_test_test_SOURCES = src/test/test_dir.c \ src/test/test_dir_common.c \ src/test/test_dir_handle_get.c \ ++ src/test/test_dos.c \ src/test/test_entryconn.c \ src/test/test_entrynodes.c \ src/test/test_guardfraction.c \ diff --cc src/test/test.c index f225fd277,f66dee2d0..cba746517 --- a/src/test/test.c +++ b/src/test/test.c @@@ -1193,6 -1201,6 +1193,7 @@@ struct testgroup_t testgroups[] = { "dir/", dir_tests }, { "dir_handle_get/", dir_handle_get_tests }, { "dir/md/", microdesc_tests }, ++ { "dos/", dos_tests }, { "entryconn/", entryconn_tests }, { "entrynodes/", entrynodes_tests }, { "guardfraction/", guardfraction_tests }, diff --cc src/test/test.h index 93d527ba1,41df6b134..b41f0e54b --- a/src/test/test.h +++ b/src/test/test.h @@@ -199,9 -190,9 +199,10 @@@ extern struct testcase_t container_test extern struct testcase_t controller_tests[]; extern struct testcase_t controller_event_tests[]; extern struct testcase_t crypto_tests[]; -extern struct testcase_t dos_tests[]; +extern struct testcase_t crypto_openssl_tests[]; extern struct testcase_t dir_tests[]; extern struct testcase_t dir_handle_get_tests[]; ++extern struct testcase_t dos_tests[]; extern struct testcase_t entryconn_tests[]; extern struct testcase_t entrynodes_tests[]; extern struct testcase_t guardfraction_tests[];
participants (1)
-
nickm@torproject.org