[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
now.
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,
big-endian...".
That comes to 18.45 exabytes per second, which should be quite
future-proof.
>> 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