From 74cd57517c10fd99345ffcc90d9376f9144e675a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 3 Jan 2015 12:34:52 -0500 Subject: [PATCH 1/2] New option "HiddenServiceAllowUnknownPorts" This allows hidden services to disable the anti-scanning feature introduced in 0.2.6.2-alpha. With this option not set, a connection to an unlisted port closes the circuit. With this option set, only a RELAY_DONE cell is sent. Closes ticket #14084. --- changes/bug14084 | 6 ++++++ doc/tor.1.txt | 4 ++++ src/or/config.c | 1 + src/or/connection_edge.c | 9 +++++++-- src/or/rendservice.c | 26 +++++++++++++++++++++++--- 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 changes/bug14084 diff --git a/changes/bug14084 b/changes/bug14084 new file mode 100644 index 0000000000..c7f053e16e --- /dev/null +++ b/changes/bug14084 @@ -0,0 +1,6 @@ + o Minor features: + - New option "HiddenServiceAllowUnknownPorts" to allow hidden + services to disable the anti-scanning feature introduced in + 0.2.6.2-alpha. With this option not set, a connection to an + unlisted port closes the circuit. With this option set, only a + RELAY_DONE cell is sent. Closes ticket #14084. \ No newline at end of file diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 4e3e07e2d3..92a6a6ac6a 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -2071,6 +2071,10 @@ The following options are used to configure a hidden service. found in the hostname file. Clients need to put this authorization data in their configuration file using **HidServAuth**. +[[HiddenServiceAllowUnknownPorts]] **HiddenServiceAllowUnknownPorts** **0**|**1**:: + If set to 1, then connections to unrecognized ports do not cause the + current hidden service to close rendezvous circuits. (Default: 0) + [[RendPostPeriod]] **RendPostPeriod** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: Every time the specified period elapses, Tor uploads any rendezvous service descriptors to the directory servers. This information is also diff --git a/src/or/config.c b/src/or/config.c index d70d6acb59..e0043d8de1 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -269,6 +269,7 @@ static config_var_t option_vars_[] = { VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL), VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL), VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL), + VAR("HiddenServiceAllowUnknownPorts",LINELIST_S, RendConfigLines, NULL), V(HiddenServiceStatistics, BOOL, "0"), V(HidServAuth, LINELIST, NULL), V(CloseHSClientCircuitsImmediatelyOnTimeout, BOOL, "0"), diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index d8f397bd90..8c3b161499 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -2610,7 +2610,9 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) n_stream->rend_data = rend_data_dup(origin_circ->rend_data); tor_assert(connection_edge_is_rendezvous_stream(n_stream)); assert_circuit_ok(circ); - if (rend_service_set_connection_addr_port(n_stream, origin_circ) < 0) { + + const int r = rend_service_set_connection_addr_port(n_stream, origin_circ); + if (r < 0) { log_info(LD_REND,"Didn't find rendezvous service (port %d)", n_stream->base_.port); /* Send back reason DONE because we want to make hidden service port @@ -2629,7 +2631,10 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) * scanning the hidden service ports. Note that this mitigates port * scanning by adding more work on the attacker side to successfully * scan but does not fully solve it. */ - return END_CIRC_AT_ORIGIN; + if (r < -1) + return END_CIRC_AT_ORIGIN; + else + return 0; } assert_circuit_ok(circ); log_debug(LD_REND,"Finished assigning addr/port"); diff --git a/src/or/rendservice.c b/src/or/rendservice.c index b9d98755ea..e14831e1be 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -129,6 +129,9 @@ typedef struct rend_service_t { * when they do, this keeps us from launching multiple simultaneous attempts * to connect to the same rend point. */ replaycache_t *accepted_intro_dh_parts; + /** If true, we don't close circuits for making requests to unsupported + * ports. */ + int allow_unknown_ports; } rend_service_t; /** A list of rend_service_t's for services run on this OP. @@ -397,6 +400,19 @@ rend_config_services(const or_options_t *options, int validate_only) return -1; } smartlist_add(service->ports, portcfg); + } else if (!strcasecmp(line->key, "HiddenServiceAllowUnknownPorts")) { + service->allow_unknown_ports = (int)tor_parse_long(line->value, + 10, 0, 1, &ok, NULL); + if (!ok) { + log_warn(LD_CONFIG, + "HiddenServiceAllowUnknownPorts should be 0 or 1, not %s", + line->value); + rend_service_free(service); + return -1; + } + log_info(LD_CONFIG, + "HiddenServiceAllowUnknownPorts=%d for %s", + (int)service->allow_unknown_ports, service->directory); } else if (!strcasecmp(line->key, "HiddenServiceDirGroupReadable")) { service->dir_group_readable = (int)tor_parse_long(line->value, @@ -3382,7 +3398,8 @@ rend_service_dump_stats(int severity) /** Given conn, a rendezvous exit stream, look up the hidden service for * 'circ', and look up the port and address based on conn-\>port. - * Assign the actual conn-\>addr and conn-\>port. Return -1 if failure, + * Assign the actual conn-\>addr and conn-\>port. Return -2 on failure + * for which the circuit should be closed, -1 on other failure, * or 0 for success. */ int @@ -3405,7 +3422,7 @@ rend_service_set_connection_addr_port(edge_connection_t *conn, log_warn(LD_REND, "Couldn't find any service associated with pk %s on " "rendezvous circuit %u; closing.", serviceid, (unsigned)circ->base_.n_circ_id); - return -1; + return -2; } matching_ports = smartlist_new(); SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p, @@ -3423,6 +3440,9 @@ rend_service_set_connection_addr_port(edge_connection_t *conn, } log_info(LD_REND, "No virtual port mapping exists for port %d on service %s", conn->base_.port,serviceid); - return -1; + if (service->allow_unknown_ports) + return -1; + else + return -2; } From 18a15747efe29d2df7a8ea852439fd30886cf9b3 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 20 Jan 2015 14:07:22 -0500 Subject: [PATCH 2/2] Expand manpage for HiddenServiceAllowUnknownPorts based on suggestions from qwerty1 and dgoulet --- doc/tor.1.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 92a6a6ac6a..a10ce16609 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -2073,7 +2073,9 @@ The following options are used to configure a hidden service. [[HiddenServiceAllowUnknownPorts]] **HiddenServiceAllowUnknownPorts** **0**|**1**:: If set to 1, then connections to unrecognized ports do not cause the - current hidden service to close rendezvous circuits. (Default: 0) + current hidden service to close rendezvous circuits. (Setting this to 0 is + not an authorization mechanism; it is instead meant to be a mild + inconvenience to port-scanners.) (Default: 0) [[RendPostPeriod]] **RendPostPeriod** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: Every time the specified period elapses, Tor uploads any rendezvous