[tor-bugs] #25882 [Core Tor/Tor]: clients not detecting stale onion service introduction points
Tor Bug Tracker & Wiki
blackhole at torproject.org
Sat Apr 28 20:53:29 UTC 2018
#25882: clients not detecting stale onion service introduction points
--------------------------+------------------------------------
Reporter: cypherpunks | Owner: (none)
Type: defect | Status: assigned
Priority: Medium | Milestone: Tor: 0.3.4.x-final
Component: Core Tor/Tor | Version:
Severity: Normal | Resolution:
Keywords: tor-hs | Actual Points:
Parent ID: #22455 | Points:
Reviewer: | Sponsor:
--------------------------+------------------------------------
Comment (by cypherpunks):
Digging a bit deeper into {{{debug.A.log}}}, we find that Tor tries some
random descriptors but ultimately keeps choosing 185.2.172.237 as an intro
point. After 06:30:17, it is the only one remaining that has not beenĀ·
{{{
$ grep "\(as intro point\)\|\(Failed to reach\)" debug.A.log | head -40
Apr 27 06:30:01.000 [info] circuit_get_open_circ_or_launch(): Chose
$DC161F3B2FF30446A14B69A1E6493FD6300A45D2~$DC161F3B2FF30446A1 at
185.50.191.250 as intro point for '[scrubbed]'.
Apr 27 06:30:01.000 [info] circuit_get_open_circ_or_launch(): Chose
$35E8B344F661F4F2E68B17648F35798B44672D7E~$35E8B344F661F4F2E6 at
146.0.32.144 as intro point for '[scrubbed]'.
Apr 27 06:30:01.000 [info] circuit_get_open_circ_or_launch(): Chose
$813BD9A5FF580C9BDDD9767E85D4CF6FC868B20D~$813BD9A5FF580C9BDD at
82.118.17.235 as intro point for '[scrubbed]'.
Apr 27 06:30:04.000 [info] circuit_get_open_circ_or_launch(): Chose
$8FA6BBB26DDD237A22DD11866D196357F29BC19E~$8FA6BBB26DDD237A22 at
134.119.217.250 as intro point for '[scrubbed]'.
Apr 27 06:30:05.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:06.000 [info] circuit_get_open_circ_or_launch(): Chose
$73A9297A6741DF33F4D1B7BB935B30B6A1D25B52~$73A9297A6741DF33F4 at
46.101.100.94 as intro point for '[scrubbed]'.
Apr 27 06:30:06.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:07.000 [info] circuit_get_open_circ_or_launch(): Chose
$E1D0BA78D83BC0A5E7F1A791973022AE15C3548E~$E1D0BA78D83BC0A5E7 at
185.100.86.249 as intro point for '[scrubbed]'.
Apr 27 06:30:07.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 2 times.
Apr 27 06:30:07.000 [info] circuit_get_open_circ_or_launch(): Chose
$500FD47E7503B0C51EAD9E250A0119EBEE56EC5C~$500FD47E7503B0C51E at
173.212.248.165 as intro point for '[scrubbed]'.
Apr 27 06:30:09.000 [info] circuit_get_open_circ_or_launch(): Chose
$FAA935B0BC3B4348CCBD3EBA95681AB51730977D~$FAA935B0BC3B4348CC at
89.163.225.7 as intro point for '[scrubbed]'.
Apr 27 06:30:10.000 [info] circuit_get_open_circ_or_launch(): Chose
$FDAC8BA3ABFCC107D1B1EAC953F195BEEBA7FF54~$FDAC8BA3ABFCC107D1 at
62.210.84.34 as intro point for '[scrubbed]'.
Apr 27 06:30:11.000 [info] circuit_get_open_circ_or_launch(): Chose
$3E515AB55BCFDD1E9ED1515B60223A08EE7710F0~$3E515AB55BCFDD1E9E at
144.76.61.48 as intro point for '[scrubbed]'.
Apr 27 06:30:11.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 3 times.
Apr 27 06:30:12.000 [info] circuit_get_open_circ_or_launch(): Chose
$3E515AB55BCFDD1E9ED1515B60223A08EE7710F0~$3E515AB55BCFDD1E9E at
144.76.61.48 as intro point for '[scrubbed]'.
Apr 27 06:30:12.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 4 times.
Apr 27 06:30:12.000 [info] circuit_get_open_circ_or_launch(): Chose
$B493C692A62D8D24E93DD50113653A4D0152B7C5~$B493C692A62D8D24E9 at
176.24.237.138 as intro point for '[scrubbed]'.
Apr 27 06:30:13.000 [info] circuit_get_open_circ_or_launch(): Chose
$3E515AB55BCFDD1E9ED1515B60223A08EE7710F0~$3E515AB55BCFDD1E9E at
144.76.61.48 as intro point for '[scrubbed]'.
Apr 27 06:30:13.000 [info] circuit_get_open_circ_or_launch(): Chose
$0F85E6DB0E4A3B6FDDF7C9452C9B5D089B11979D~$0F85E6DB0E4A3B6FDD at
31.31.73.222 as intro point for '[scrubbed]'.
Apr 27 06:30:13.000 [info] circuit_get_open_circ_or_launch(): Chose
$E0EAA536856FBD3C3AB46C2BAA398E7CDFDAFF5D~$E0EAA536856FBD3C3A at
77.87.50.6 as intro point for '[scrubbed]'.
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 5 times. Removing from descriptor.
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:15.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:15.000 [info] circuit_get_open_circ_or_launch(): Chose
$99B6BE15B92A8746D14308F6C7FD84C28034335C~$99B6BE15B92A8746D1 at
188.230.183.231 as intro point for '[scrubbed]'.
Apr 27 06:30:17.000 [info] circuit_get_open_circ_or_launch(): Chose
$D64366987CB39F61AD21DBCF8142FA0577B92811~$D64366987CB39F61AD at
37.221.162.226 as intro point for '[scrubbed]'.
Apr 27 06:30:20.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:22.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:25.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:27.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:29.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:31.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:34.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:36.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:38.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:40.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:42.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:45.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:48.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:51.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:53.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
}}}
Notice that once we reach the intro point 185.22.172.237, Tor gets stuck.
(Note that the log message about choosing 185.22.172.237 occurs 75 more
times between 06:30:53 and 06:33:59.) Note that we are not noticing that
it is unreachable, as we do for some other intro points:
{{{
$ grep "Failed" debug.A.log | more
Apr 27 06:30:05.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:05.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:06.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:06.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:07.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:07.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 2 times.
Apr 27 06:30:08.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:09.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:10.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:11.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:11.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 3 times.
Apr 27 06:30:12.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:12.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 4 times.
Apr 27 06:30:13.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 5 times. Removing from descriptor.
Apr 27 06:30:13.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:15.000 [info] circuit_about_to_free(): Failed intro circ
[scrubbed] to [scrubbed] (building circuit to intro point). Marking intro
point as possibly unreachable.
}}}
One of the problems with these logs is that my Tor is trying to connect to
several different onion services around the same time. As you can see
here, the descriptors for three of the hidden services in question are
actually re-fetched, as they ought to be, although after 06:30:18, there
is "1 options left" for the service that is stuck with 185.22.172.237
(note: it might be nice to have some kind of unique identifier, perhaps
the stream ID, for each of these hidden services, so that we can correlate
them with each other in the log, rather than just see the same
"[scrubbed]" for each):
{{{
$ grep -i "rend_client_report_intro_point_failure" debug.A.log | more
Apr 27 06:30:04.000 [info] rend_client_report_intro_point_failure(): 5
options left for [scrubbed].
Apr 27 06:30:04.000 [info] rend_client_report_intro_point_failure(): 9
options left for [scrubbed].
Apr 27 06:30:05.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:05.000 [info] rend_client_report_intro_point_failure(): 5
options left for [scrubbed].
Apr 27 06:30:05.000 [info] rend_client_report_intro_point_failure(): 8
options left for [scrubbed].
Apr 27 06:30:05.000 [info] rend_client_report_intro_point_failure(): 4
options left for [scrubbed].
Apr 27 06:30:06.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:06.000 [info] rend_client_report_intro_point_failure(): 6
options left for [scrubbed].
Apr 27 06:30:06.000 [info] rend_client_report_intro_point_failure(): 3
options left for [scrubbed].
Apr 27 06:30:06.000 [info] rend_client_report_intro_point_failure(): 5
options left for [scrubbed].
Apr 27 06:30:07.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 2 times.
Apr 27 06:30:07.000 [info] rend_client_report_intro_point_failure(): 3
options left for [scrubbed].
Apr 27 06:30:07.000 [info] rend_client_report_intro_point_failure(): 7
options left for [scrubbed].
Apr 27 06:30:07.000 [info] rend_client_report_intro_point_failure(): 4
options left for [scrubbed].
Apr 27 06:30:08.000 [info] rend_client_report_intro_point_failure(): 6
options left for [scrubbed].
Apr 27 06:30:08.000 [info] rend_client_report_intro_point_failure(): 6
options left for [scrubbed].
Apr 27 06:30:08.000 [info] rend_client_report_intro_point_failure(): 2
options left for [scrubbed].
Apr 27 06:30:08.000 [info] rend_client_report_intro_point_failure(): 3
options left for [scrubbed].
Apr 27 06:30:08.000 [info] rend_client_report_intro_point_failure(): 5
options left for [scrubbed].
Apr 27 06:30:09.000 [info] rend_client_report_intro_point_failure(): 3
options left for [scrubbed].
Apr 27 06:30:09.000 [info] rend_client_report_intro_point_failure(): 1
options left for [scrubbed].
Apr 27 06:30:09.000 [info] rend_client_report_intro_point_failure(): 4
options left for [scrubbed].
Apr 27 06:30:09.000 [info] rend_client_report_intro_point_failure(): 2
options left for [scrubbed].
Apr 27 06:30:10.000 [info] rend_client_report_intro_point_failure(): 4
options left for [scrubbed].
Apr 27 06:30:10.000 [info] rend_client_report_intro_point_failure(): 1
options left for [scrubbed].
Apr 27 06:30:10.000 [info] rend_client_report_intro_point_failure(): 3
options left for [scrubbed].
Apr 27 06:30:11.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 3 times.
Apr 27 06:30:11.000 [info] rend_client_report_intro_point_failure(): 1
options left for [scrubbed].
Apr 27 06:30:11.000 [info] rend_client_report_intro_point_failure(): No
more intro points remain for [scrubbed]. Re-fetching descriptor.
Apr 27 06:30:12.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 4 times.
Apr 27 06:30:12.000 [info] rend_client_report_intro_point_failure(): 1
options left for [scrubbed].
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 5 times. Removing from descriptor.
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure(): No
more intro points remain for [scrubbed]. Re-fetching descriptor.
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure():
Failed to reach this intro point 1 times.
Apr 27 06:30:13.000 [info] rend_client_report_intro_point_failure(): 6
options left for [scrubbed].
Apr 27 06:30:15.000 [info] rend_client_report_intro_point_failure(): No
more intro points remain for [scrubbed]. Re-fetching descriptor.
Apr 27 06:30:15.000 [info] rend_client_report_intro_point_failure(): 2
options left for [scrubbed].
Apr 27 06:30:18.000 [info] rend_client_report_intro_point_failure(): 1
options left for [scrubbed].
}}}
Note also that in {{{circuit_about_to_free}}} in {{{circuitlist.c}}}, we
never seem to record any timeouts for the bad intro point, despite the
fact that we are deciding that it is too old (see description of ticket
and comment:6 above:
{{{
if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT &&
ocirc->rend_data) {
/* treat this like getting a nack from it */
log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). %s",
safe_str_client(rend_data_get_address(ocirc->rend_data)),
safe_str_client(build_state_get_exit_nickname(ocirc->build_state)),
timed_out ? "Recording timeout." : "Removing from descriptor.");
rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
ocirc->rend_data,
timed_out ?
INTRO_POINT_FAILURE_TIMEOUT :
INTRO_POINT_FAILURE_GENERIC);
}
}}}
The circuits are indeed reaped. For example, circuit 878 is freed about
one second after its purpose is reassigned:
{{{
Apr 27 06:30:20.000 [info] circuit_get_open_circ_or_launch(): Chose
$0074ECA82BD58B8BB1909C9C4F237FD9779B23FC~$0074ECA82BD58B8BB1 at
185.22.172.237 as intro point for '[scrubbed]'.
Apr 27 06:30:20.000 [debug] circuit_find_to_cannibalize(): Hunting for a
circ to cannibalize: purpose 6, uptime 0, capacity 1, internal 1
Apr 27 06:30:20.000 [info] circuit_launch_by_extend_info(): Cannibalizing
circ 3959015402 (id: 878) for purpose 6 (Hidden service client: Connecting
to intro point)
Apr 27 06:30:20.000 [debug] circuit_change_purpose(): changing purpose of
origin circ 878 from "General-purpose client" (5) to "Hidden service
client: Connecting to intro point" (6)
[...]
Apr 27 06:30:21.000 [debug] circuit_get_by_circid_channel_impl():
circuit_get_by_circid_channel_impl() returning circuit 0x125e268 for
circ_id 3959015402, channel ID 174 (0x1afb648)
Apr 27 06:30:21.000 [debug] circuitmux_append_destroy_cell(): Cmux at
0x14fd5a0 queued a destroy for circ 3959015402, cmux counter is now 1,
global counter is now 1
Apr 27 06:30:21.000 [debug] circuitmux_append_destroy_cell(): Primed a
buffer.
Apr 27 06:30:21.000 [debug] channel_write_cell_generic_(): Writing p
0x14838f0 to channel 0x1afb648 with global ID 174
Apr 27 06:30:21.000 [debug] circuit_get_by_circid_channel_impl():
circuit_get_by_circid_channel_impl() returning circuit 0x125e268 for
circ_id 3959015402, channel ID 174 (0x1afb648)
Apr 27 06:30:21.000 [debug] channel_tls_get_overhead_estimate_method():
Estimated overhead ratio for TLS chan 174 is 1.040139
Apr 27 06:30:21.000 [debug] channel_update_xmit_queue_size(): Increasing
queue size for channel 174 by 534 from 0 to 534
Apr 27 06:30:21.000 [debug] channel_update_xmit_queue_size(): Increasing
global queue size by 534 for channel 174, new size is 534
Apr 27 06:30:21.000 [debug] circuitmux_notify_xmit_destroy(): Cmux at
0x14fd5a0 sent a destroy, cmux counter is now 0, global counter is now 0
Apr 27 06:30:21.000 [debug] channel_send_destroy(): Sending destroy
(circID 3959015402) on channel 0x1afb648 (global ID 174)
Apr 27 06:30:21.000 [info] circuit_free(): Circuit 0 (id: 878) has been
freed.
}}}
But why is the timeout not recorded? Looking in
{{{circuit_about_to_free}}} in {{{circuitlist.c}}}, have we not set
{{{ocirc->rend_data}}}? Or have we failed to set the purpose
to{{{CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT}}} (I would have guessed that we
do this in {{{send_introduce1}}} in {{{circuituse.c}}}.) More
investigation would be useful, although I would surmise that adding
debugging statements to {{{circuit_about_to_free}}} would be the next
step.
--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/25882#comment:11>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online
More information about the tor-bugs
mailing list