[tor-dev] Pre-draft of Proposal XXX: Extended ORPort and TransportControlPort

George Kadianakis desnacked at riseup.net
Fri Mar 9 10:01:01 UTC 2012

Nick Mathewson <nickm at alum.mit.edu> writes:

> On Thu, Jan 26, 2012 at 8:38 PM, George Kadianakis <desnacked at riseup.net> wrote:
>> After discussion in tickets #4773 and #3587 this is a pre-draft of a
>> proposal that revamps the Extended ORport, introduced in proposal 180,
>> <snip>
>>   communication between the tor process and the pluggable transport
>>   proxy. To achieve this, this proposal refactors the extended ORPort
>>   protocol specified in Proposal 180, and introduces a new port,
>>   TransportControlPort, whose sole role is the exchange of control
>>   information between transport proxies and tor.
> So before we get too far into this, let's do a protocol overview! I'd
> suggest inserting something like this into the text, assuming that it
> is actually what you meant:
> "Server-side Transports need to talk to the Tor server about
> individual connections, and continue to do so as the connection is
> ongoing.  To do so,
> the transports deliver each connection to an "Extended ORPort", where
> they provide metadata and agree on an identifier for each tunneled
> connection.  Once this handshake occurs, the OR protocol proceeds
> unchanged.
> Additionally, each transport maintains a single connection to Tor's
> "TransportControlPort", where it receives instructions from Tor about
> rate-limiting on individual connections.

A similar string to this, can be found in the beginning of section
3. . I think we should remove the first paragraph of section 3, and
put your version of the string in the end of section 2.

>> 3. The new extended ORPort protocol
>>  Server transport proxies may need to connect to the bridge and pass
>>  additional information about client connections that the bridge
>>  would ordinarily receive from the kernel's TCP stack.  To do this,
>>  they connect to the "extended server port" as given in
>>  EXTENDED_SERVER_PORT, send a short amount of information, wait for a
>>  response, and then send the user traffic on that port.
>>  The extended server port protocol is as follows:
>>     COMMAND [2 bytes, big-endian]
>>     BODYLEN [2 bytes, big-endian]
>>     BODY [BODYLEN bytes]
>>     Commands sent from the transport proxy to the bridge are:
>>     [0x0000] DONE: There is no more information to give. (body ignored)
> Let's add, "the next bytes sent by the transport will be those
> tunneled over it."

I agree.

>>     [0x0001] USERADDR: an address:port string that represents the user's
>>       address.
>>     [0x0002] WANT_CONTROL: A body-less message which indicates that
>>       the transport proxy wants to use the TransportControlPort of
>>       the bridge.  It SHOULD be followed by a CONTROL command from
>>       the bridge, otherwise the transport may close the connection.
>> # will this work?
> Hm.  I think it'd be better to have this command mean "We support the
> transportcontrolport protocol," not "you must use the
> transportcontrolport protocol!"  After all, if Tor _doesn't_ tell the
> transport about rate-limiting, it's not like anything breaks
> disastrously.

Hm, when I thought of 'WANT_CONTROL', I was considering that there
might be transports that absolutely _require_ the use of
TransportControlPort. Since we don't have such transports at the
moment, and the short-term future transports don't seem to require
TransportControlPort, I guess it could be OK to diss WANT_CONTROL for

Still, I'm not sure if tor should do business with a transport proxy
that does _not_ support the TransportControlPort protocol. It wouldn't
surprise me if there are bridge operators out there who consider
rate-limiting essential.

>>     Replies sent from tor to the proxy are:
>>     [0x1000] OKAY: Send the user's traffic. (body ignored)
>>     [0x1001] DENY: Tor would prefer not to get more traffic from
>>       this address for a while. (body ignored)
>>     [0x1002] CONTROL: a NUL-terminated "identifier" string, followed
>>       by a second NUL-terminated string of the <address>:<port> of
>>       the TransportControlPort. The pluggable transport proxy must
>>       use the "identifier" to access the TransportControlPort.
>> # pass TransportControlPort <address>:<port> through env. vars?
> Seems wise, sure.

OK, then, CONTROL should simply contain the TransportControlPort
identifier and we should update 180 to specify how we pass the
TransportControlPort creds through environment variables.

>> # what should parties do when they receive a command they don't
>> # understand?  should we enforce forward-compatibility with protocol
>> # versioning or with "ignore commands you don't understand", or what?
> Let's say "ignore."  If you want, we can reserve the top bit of each
> command to indicate "you must understand this; if you don't, close the
> connection."

'ignore' sounds fine. If you think that reserving the top bit will be
helpful in the long-run, I guess we should do it.

>>  [We could also use an out-of-band signalling method to tell Tor
>>  about client addresses, but that's a historically error-prone way
>>  to go about annotating connections.]
> Yes; let's not do that.

That was actually your own text copied from 180. Since you seem to
agree with your one-year-younger self, I guess we can erase it from
the proposals :)

>> The new TransportControlPort protocol
>>  The TransportControlPort protocol is as follows:
>>     COMMAND [2 bytes, big-endian]
>>     BODYLEN [2 bytes, big-endian]
>>     BODY [BODYLEN bytes]
>>     Association commands sent from the transport proxy to the bridge
>>     are:
>>     [0x0000] ASSOCIATE: a NUL-terminated "identifier" string. See
>>      'Association' section below.
> Hm.  I think that each command should have an associated identifier,
> and that identifiers should be (say) 16-byte binary values.  All this
> hex encoding/decoding seems pointless, since this isn't a
> text-oriented protocol.  So how about
>      ConnectionID [16 bytes]
>      Command [2 bytes]
>      Bodylen [2 bytes]
>      Body [bodylen bytes]

Looks good!

>>     Association commands sent from the bridge to the transport proxy
>>     are:
>>     [0x1000] ASSOCIATED: Sent upon receiving a legit ASSOCIATE
>>       command from a transport proxy. (body ignored)
>>     [0x1001] NOT_ASSOCIATED: Sent after the bridge receives a
>>       non-legit ASSOCIATE command from a transport proxy. Also sent
>>       when the bridge receives a non-ASSOCIATE command from a
>>       non-associated transport proxy. Upon sending this command, the
>>       bridge SHOULD close the connection. (body ignored)
>>     Configuration commands sent from the transport proxy to the
>>     bridge:
>>     [0x0001] RATE_LIMITED: Message confirming that the rate limiting
>>       request of the bridge was carried out successfully (body
>>       ignored). See the 'Rate Limiting' section below.
>>     [0x0001] NOT_RATE_LIMITED: Message notifying that the transport
>>       proxy failed to carry out the rate limiting request of the
>>       bridge (body ignored). See the 'Rate Limiting' section below.
>>     Configuration commands sent from the bridge to the transport
>>     proxy are:
>>     [0x1002] RATE_LIMIT: Carries information on how the pluggable
>>       transport proxy should rate-limit its traffic. See the 'Rate
>>       Limiting' section below.
>> # what should parties do when they receive a command they don't understand?
> Send an "unrecognized command error", perhaps.  Or ignore it.  If the
> latter, let's add a way to declare what version of this protocol you
> will understand.

Since we like 'ignore' in the 'ExtendedOR Protocol', we can use
'ignore' here too. Maybe.

>> 3.1. Association and identifier creation
>> For Tor and a transport proxy to communicate using the
>> TransportControlPort, an identifier must have already been negotiated
>> using the 'CONTROL' command of Extended ORPort.
>> The TransportControlPort identifier should not be predictable by a
>> user who hasn't received a 'CONTROL' command from the Extended
>> ORPort. For this reason, the TransportControlPort identifier should
>> not be cryptographically-weak or deterministically created.
>> Tor should create its identifiers by generating 16 bytes of random
>> data and hashing them with the SHA256 cryptographic hash function.
>> The identifier string transmitted with the 'CONTROL' command should be
>> the hex representation of the SHA256 output.
> The hashing step seems pointless; why not just generate 16 random
> bytes and use those?

I'm stupid.

>> 4. Configuration commands
>> 4.1. Rate Limiting
>> A tor relay should be able to inform a transport proxy in real-time
>> about its rate-limiting needs.
>> This can be achieved by using the TransportControlPort and sending a
>> 'RATE_LIMIT' command to the transport proxy.
>> The body of the 'RATE_LIMIT' command should carry two integers, in
>> NUL-terminated ASCII string format, representing the bandwidth rate
>> and bandwidth burst in 'bytes per second', that the transport proxy
>> must set.
>> # better transmit format? After reading langsec.org, I prefer to avoid
>> # length fields. Not that this format is bug-proof...
> 4 bytes, big-endian, I'd say.

I like. That was what I wanted to do originally, but I then discarded
it as non-future-proof enough.

Let's pump it up to "The body of the 'RATE_LIMIT' command should carry
two integers describing 'bytes per second'. Each of them is 8 bytes,

That comes to 18.45 exabytes per second, which should be quite

>> When the transport proxy sets the appropriate rate limiting, it should
>> send back a 'RATE_LIMITED' command. If it fails while setting up rate
>> limiting, it should send back a 'NOT_RATE_LIMITED' command.
>> After sending a 'RATE_LIMIT' command. the tor bridge might want to
>> stop pushing data to the transport proxy, till it receives a
>> 'RATE_LIMITED' command. If, instead, it receives a 'NOT_RATE_LIMITED'
>> command it might want to shutdown its connections to the transport
>> proxy.
>> # is this realistic?
> Hm.  There probably also wants to be an overall rate limit that
> applies to all connections.  Also, there should be a way for the
> transport to report to Tor how many bytes it's actually using, I
> think, if the bytes on the wire are more vebose than the traffic they
> encode.

Actually, when I was thinking of 'RATE_LIMIT', I was thinking that the
rate limit value describes "the overall rate limit that applies to all
connections". I _wasn't_ thinking of it as per-connection.
I know it feels stupid and/or unintuitive to specify the global rate
limit in a per-connection stream, but it seemed like the simplest way
to do it. What do you think?

I also agree that there should be a way for the transport to report to
Tor how many bytes it's actually using.

Specifically, my proposal does *not* specify how transport proxies
pass usage statistics to tor. This is quite needed at the moment.

>> 5. Security Considerations
>> Extended ORPort or TransportControlPort do _not_ provide link
>> confidentiality, authentication or integrity. Sensitive data, like
>> cryptographic material, should not be transferred through them.
>> Note that an attacker with superuser access, is able to sniff network
>> traffic, and capture TransportControlPort identifiers and any data
>> passed through those ports.
>> # Is it worth adding an SSL layer (passing pub. key fpr via
>> # env. vars?)? :/
> I say no; though it probably _is_ worthwhile to say "This should only
> use localhost, and should shout very loudly if you try to bind or
> connect somewhere else with it."

Sounds good.

>> # Talk about Incentives of tor or transport proxies to comply to the
>> # wishes of each other. Ways to detect nonconformism. (threat
>> # model. Should tor speak with 3v1l transport proxies in the first
>> # place?)
> I disagree with that; the transport proxies are run by the bridge
> operators and need to do more or less what they're supposed to do.
> Trying to get proxies to be sandboxable or something seems like a much
> bigger and sorta unrelated task.
> yrs,

If you haven't done it already, I'll try to update the proposal today
or tomorrow, and also specify how statistics should be passed around.

More information about the tor-dev mailing list