Opened 5 years ago

Closed 5 years ago

#11469 closed defect (fixed)

Exit not using one hop circuit to Directory Server

Reported by: bburley Owned by: nickm
Priority: High Milestone: Tor: 0.2.5.x-final
Component: Core Tor/Tor Version:
Severity: Keywords: one-hop directory 024-backport
Cc: arma Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

I've set up a lab to learn about Tor. All nodes running within Xen 6.2 on FreeBSD 10 running Tor version 2.4.19.

All clients can build circuits and functionality looks as expected. However, while entry and relay nodes use the encrypted, one-hop circuit to communicate with the Directory Server, the exit node does not. The exit node communicates directly with the dir port on the directory server (http). I'm using tcpdump -nvvv -A on the specific interfaces to see the traffic.

All nodes in the lab are essentially clones. The torrc file is changed on each node to reflect client, entry, relay, and exit roles. The only difference between the nodes that use the one-hop circuilt and the one that doesn't is the "accept" policy on the exit node. I don't see how that relates, but when I remove the "accept" policy and add a policy to "reject *:*" the one-hop circuit is then used . I've gone over this quite a bit. It may be a bug.

Child Tickets

Change History (24)

comment:1 Changed 5 years ago by bburley

Priority: normalmajor

comment:2 Changed 5 years ago by bburley

I've spent time trying to isolate this further. It appears that when there is an exit policy that "accepts" anything, even the default accept policy, I see a "use_begindir 0" in the log file. shown at the end of the line here:

Apr 30 13:43:28.000 [debug] void directory_initiate_command_rend(const char *, const tor_addr_t *, uint16_t, uint16_t, const char *, uint8_t, uint8_t, dir_indirection_t, const char *, const char *, size_t, time_t, const rend_data_t *)(): anonymized 0, use_begindir 0.

When I have an exit policy that "rejects" everything, I see a "use begindir 1" in the log file. shown at the end of the line here:

Apr 30 13:43:42.000 [debug] void directory_initiate_command_rend(const char *, const tor_addr_t *, uint16_t, uint16_t, const char *, uint8_t, uint8_t, dir_indirection_t, const char *, const char *, size_t, time_t, const rend_data_t *)(): anonymized 0, use_begindir 1.

When I see "use_begindir 0" the node connects to the directory unencrypted.

When I see "use_begindir 1" the node connects to the directory encrypted using the one-hop circuit.

This seems similar to the behavior discussed in Trac Ticket 10849. I applied the patch referred to in ticket 10849 but that did resolve this issue.

comment:3 Changed 5 years ago by nickm

So, it is normal for all nodes -- not just exits -- to use unencrypted connections to upload descriptors do the directory. When use_begindir is 0 in the call to directory_initiate_command_rend() above, in your testing, what are the values of dir_purpose and router_purpose?

comment:4 Changed 5 years ago by bburley

Thanks, Nick. For some reason I'm not seeing other node types communicate unencrypted, just the exit. Anyway, dir_purpose and router_purpose are not in the log files. Can you please advise how I can determine these values?

comment:5 Changed 5 years ago by dcole

In the scenario described,

dir_purpose=8
router_purpose=0
use_begindir=0

comment:6 in reply to:  5 Changed 5 years ago by nickm

Replying to dcole:

In the scenario described,

dir_purpose=8

Okay, so it's uploading its own descriptor:

/** A connection to a directory server: upload a server descriptor. */
#define DIR_PURPOSE_UPLOAD_DIR 8

That's normal to do over an HTTP connection.

Are the other, non-exit routers really not uploading their descriptors over HTTP?

comment:7 Changed 5 years ago by dcole

Hrmm, I am not sure if that is the right question to ask. Isn't it really just a problem that it's not using the OR port when there are certain exit policy rules set? I was trying to learn enough about libevent to backtrace this problem to compare exactly what happens when there are these two scenarios in the torrc:

ExitPolicy accept *:1194,reject *:*
#ExitPolicy reject *:*

If you swap the comments back and forth while doing a tcpdump you will see the difference I am talking about. The public key and such all gets dumped in plaintext in the configuration listed, and if you swap the comment to the other line, it all becomes encrypted.

Last edited 5 years ago by dcole (previous) (diff)

comment:8 Changed 5 years ago by nickm

ExitPolicy doesn't have anything to do with which directory servers a relay uses as directory services; it only affects which addresses a relay is willing to make connections to in order to handle client requests.

comment:9 Changed 5 years ago by dcole

Isn't that the point that the exit policy shouldn't have any effect on how the node communicates to the dir server? In other words, when I have a "ExitPolicy reject *:*" my traffic goes to the directory servers OR port - 8999, vs 8000 when I have that other policy set. I'm not sure why it has any effect, which is what I think the spirit of this bug report is about.

Version 0, edited 5 years ago by dcole (next)

comment:10 Changed 5 years ago by nickm

Isn't that the point that the exit policy shouldn't have any effect on how the node communicates to the dir server?

Yes, that's right. I think I misunderstood your last comment.

So in this case, the thing to reproduce is to try to figure out why the regular non-exit nodes are not using a regular HTTP connection.

On a regular (non-exit) relay, what other arguments are passed to directory_initiate_command_rend() when dir_purpose is 8?

comment:11 Changed 5 years ago by nickm

Keywords: 024-backport added
Milestone: Tor: 0.2.5.x-final
Owner: set to nickm
Status: newassigned

Oh hey, this is some bad code. In directory_post_to_dirservers, we do:

      post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) ||
        !fascist_firewall_allows_address_dir(&ds_addr, ds->dir_port);
      directory_initiate_command_routerstatus(rs, dir_purpose,
                                              router_purpose,
                                              post_via_tor,
                                              NULL, payload, upload_len, 0);

But note that the 4th argument to directory_initiate_command_routerstatus is not a boolean; it's a dir_indirection_t. So the possible values are DIRIND_ANON and DIRIND_ONEHOP.

Later, in directory_command_should_use_begindir(), some DIRIND_ONEHOP values turn into DIRIND_DIRECT, if directory_fetches_from_authorities() is true.

This could be far more broken than it is. Writing a patch.

comment:12 Changed 5 years ago by nickm

The problematic code was introduced in 5cbeb6080, which went into 0.2.4.3-alpha.

comment:13 Changed 5 years ago by nickm

This could be far more broken than it is.

The reason this could be far more broken is that, when the purpose_needs_anonymity() returns true, we set post_via_tor to 1, which just happens to be DIRIND_ANONYMOUS. :p

comment:14 in reply to:  10 Changed 5 years ago by dcole

Replying to nickm:

Isn't that the point that the exit policy shouldn't have any effect on how the node communicates to the dir server?

Yes, that's right. I think I misunderstood your last comment.

So in this case, the thing to reproduce is to try to figure out why the regular non-exit nodes are not using a regular HTTP connection.

why exactly would you ever want to use a regular http connection for passing that information? Am I missing something about the way that works? We can discuss that in a different forum if necessary. Anyhow, I follow what you are saying about how this was happening as I was beginning to draw the same conclusion. I am just unsure

of the "why" of it.

comment:15 Changed 5 years ago by nickm

Cc: arma added
Status: assignedneeds_review

Candidate fix is in branch 'bug11469_024' in my public repository. The branch is against maint-0.2.4, though I suspect it will merge cleanly into master.

why exactly would you ever want to use a regular http connection for passing that information?

I think the original rationale was that:

  • all of this information was publicly associated with the uploading IP, and as such encrypting it wouldn't actually protect anything.
  • using a separate port for uploads would allow directory authorities to throttle downloads without harming uploads.

Though there may have been more to it. I've asked Roger if he remembers.

comment:16 Changed 5 years ago by arma

Clients use begindir so it's harder to fingerprint and prevent their directory fetches.

Relays don't use begindir to avoid loading down the directory authorities with ssl handshakes (heavyweight) simply for an http directory publish/fetch (lightweight).

Load on directory authorities seems like it should come primarily from a) clients that are bootstrapping, though we're hoping to resolve that bottleneck with the fallback directory mirrors, and b) relays. It'd be a shame to magnify part 'b' by a lot.

comment:17 Changed 5 years ago by nickm

It looks like the bug here, which was in Tor since 0.2.4.3-alpha, already magnified part b by a lot and we didn't notice. Does that mean we should change our reasoning here?

comment:18 in reply to:  17 Changed 5 years ago by bburley

Replying to nickm:

It looks like the bug here, which was in Tor since 0.2.4.3-alpha, already magnified part b by a lot and we didn't notice. Does that mean we should change our reasoning here?

I agree with you Nick. I think the reasoning behind not encrypting communications with the directories may be outdated. With cheaper, faster everything, and the growth of the infrastructure, conserving resources may not be as valid of a point in a "cost vs. security" situation.

On the security-side of the discussion, when someone decides to somewhat expose themselves by contributing to the Tor infrastructure, if something can be done to reasonably limit that exposure, it should be done. Taking steps to operate in bridge mode and other attempts to look "normal" can be blown away by communicating in the clear with the directories. I believe, in my test environment, that I could enumerate my infrastructure by looking at the unencrypted directory traffic. I'll will look closer, but believe this is the case.

Thanks to all in this discussion.

comment:19 Changed 5 years ago by nickm

Taking steps to operate in bridge mode and other attempts to look "normal" can be blown away by communicating in the clear with the directories

But bridges don't communicate in the clear, do they?

I believe, in my test environment, that I could enumerate my infrastructure by looking at the unencrypted directory traffic

if you're an adversary trying to enumerate the Tor network, you could do that (excluding bridges and clients) by just connecting to the directory authorities yourself and downloading the consensus document. Having the non-bridge Tor relays and directory authorities themselves be undetectable is not part of the current design. An attacker doesn't need to enumerate them: the directory infrastructure enumerates them for you.

Bridges and clients, on the other hand, don't make unencrypted directory connections (I certainly hope), so trying to enumerate them by plaintext patterns really shouldn't work.

To be clear, I think there could be a case to be made for "relays should never make unencrypted directory connections", but it's not an obvious case fwict. I think we should open a new ticket for that, so that this one can be about the breakage in the current behavior wrt the indirection argument in directory_post_to_dirservers().

comment:20 Changed 5 years ago by nickm

I think we should open a new ticket for that,

See #11973

comment:21 in reply to:  17 Changed 5 years ago by nickm

Replying to nickm:

It looks like the bug here, which was in Tor since 0.2.4.3-alpha, already magnified part b by a lot and we didn't notice. Does that mean we should change our reasoning here?

Roger pointed out to me on IRC that the bug here made relay uploads be done with encryption, but that cache downloads are still done directly. Cache downloads happen more frequently and use much more data, so they're probably a much larger share of the load in (b).

comment:22 in reply to:  15 Changed 5 years ago by dcole

Replying to nickm:

Candidate fix is in branch 'bug11469_024' in my public repository. The branch is against maint-0.2.4, though I suspect it will merge cleanly into master.

why exactly would you ever want to use a regular http connection for passing that information?

I think the original rationale was that:

  • all of this information was publicly associated with the uploading IP, and as such encrypting it wouldn't actually protect anything.
  • using a separate port for uploads would allow directory authorities to throttle downloads without harming uploads.

Though there may have been more to it. I've asked Roger if he remembers.

It appears that the branch referenced fixes the actual code bug in my testing. As for the rest of the discussion, I will take it to the other ticket.

comment:23 Changed 5 years ago by nickm

Milestone: Tor: 0.2.5.x-finalTor: 0.2.4.x-final

Merged to 0.2.5, marked for possible backport to 0.2.4. My inclination is "no backport" since the current behavior doesn't appear to be hurting anything.

comment:24 Changed 5 years ago by arma

Milestone: Tor: 0.2.4.x-finalTor: 0.2.5.x-final
Resolution: fixed
Status: needs_reviewclosed

We seem to be ok. Closing on the theory that we have thousands of tickets open and this one is adequately resolved.

Note: See TracTickets for help on using tickets.