After discussion in tickets #4773 and #3587 this is a pre-draft of a proposal that revamps the Extended ORport, introduced in proposal 180, and specifies the new TransportControlPort.
Comments are marked with '#', and there is also: https://trac.torproject.org/projects/tor/ticket/4773#comment:5
Note that this proposal is not ready for prime time. It needs more thought and lots of editing to become functional and implementable.
Inlining:
Filename: X Title: Extended ORPort and TransportControlPort Author: X Created: X Status: worse-than-draft-still-probably-more-thoughtful-than-sopa
1. Overview
Proposal 180 defined Tor pluggable transports, a way to decouple protocol-level obfuscation from the core Tor protocol in order to better resist client-bridge censorship. This is achieved by introducing pluggable transport proxies, programs that obfuscate Tor traffic to resist DPI detection.
Proposal 180 defined a way for pluggable transport proxies to communicate with local tor clients and bridges, so as to exchange traffic. This document extends this communication protocol, so that pluggable transport proxies can exchange arbitrary operational information and metadata with tor clients and bridges.
2. Motivation
The communication protocol specified in Proposal 180 gives a way for transport proxies to announce the IP address of their clients to tor. Still, modern pluggable transports might have more (?) needs than this. For example:
1. Tor might want to inform pluggable transport proxies on how to rate-limit incoming or outgoing connections.
2. Server pluggable transport proxies might want to pass client information to an anti-active-probing system controlled by tor.
3. Tor might want to temporarily stop a transport proxy from obfuscating traffic.
To satisfy the above use cases, there must be real-time 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.
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)
[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?
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?
# 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?
[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.]
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.
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?
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.
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...
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?
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?)? :/
# 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?)
6. Future
In the future, we might have pluggable transports which require the _client_ transport proxy to use the TransportControlPort and exchange control information with the tor client. The current proposal doesn't yet support this, but we should not add functionality that will prevent it from being possible.
On Thu, Jan 26, 2012 at 8:38 PM, George Kadianakis desnacked@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, and specifies the new TransportControlPort.
Comments are marked with '#', and there is also: https://trac.torproject.org/projects/tor/ticket/4773#comment:5
Note that this proposal is not ready for prime time. It needs more thought and lots of editing to become functional and implementable.
Inlining:
Filename: X Title: Extended ORPort and TransportControlPort Author: X Created: X Status: worse-than-draft-still-probably-more-thoughtful-than-sopa
I've got a commitment to revise this and do a (not-yet-merged) implementation by the middle of this month, so I guess I should get moving on that!
- Overview
Proposal 180 defined Tor pluggable transports, a way to decouple protocol-level obfuscation from the core Tor protocol in order to better resist client-bridge censorship. This is achieved by introducing pluggable transport proxies, programs that obfuscate Tor traffic to resist DPI detection.
Proposal 180 defined a way for pluggable transport proxies to communicate with local tor clients and bridges, so as to exchange traffic. This document extends this communication protocol, so that pluggable transport proxies can exchange arbitrary operational information and metadata with tor clients and bridges.
- Motivation
The communication protocol specified in Proposal 180 gives a way for transport proxies to announce the IP address of their clients to tor. Still, modern pluggable transports might have more (?) needs than this. For example:
1. Tor might want to inform pluggable transport proxies on how to rate-limit incoming or outgoing connections.
2. Server pluggable transport proxies might want to pass client information to an anti-active-probing system controlled by tor.
3. Tor might want to temporarily stop a transport proxy from obfuscating traffic.
To satisfy the above use cases, there must be real-time 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.
- 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."
[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.
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.
# 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."
[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.
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]
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.
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?
- 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.
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.
- 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."
# 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,
Nick Mathewson nickm@alum.mit.edu writes:
On Thu, Jan 26, 2012 at 8:38 PM, George Kadianakis desnacked@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.
- 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.
- 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.
- 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.
On Fri, Mar 9, 2012 at 5:01 AM, George Kadianakis desnacked@riseup.net wrote: [...]
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.
I think we'll do better to just support stuff that doesn't support this protocol. Yes, it's important for quality-of-implementation, but from a development POV, it is a pain to require that every plugin developer support this protocol too -- and that you support this protocol before you can even test your plugin with Tor.
[...] Snipping stuff where we don't disagree about what to do with the proposal.
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.
If we're trying that hard to be future-proof, let's have separate read and write caps, in case we need them someday.
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 think we could probably get away with a global rate limit here.
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.
We could have a similar BYTES_USED command sent from the proxy to Tor. Probably we should reserve a range of command values for use by commands like this where the transport proxy is reporting stuff to Tor that isn't in response to a command from Tor.
looking forward to the next version,
Nick Mathewson nickm@alum.mit.edu writes:
On Fri, Mar 9, 2012 at 5:01 AM, George Kadianakis desnacked@riseup.net wrote: [...]
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.
If we're trying that hard to be future-proof, let's have separate read and write caps, in case we need them someday.
I see what you mean :) OK, the updated proposal is doing it with _4_ bytes, big-endian.
The Tor developers of the future, can make a 'RATE_LIMIT_2' command.
<snip>
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.
We could have a similar BYTES_USED command sent from the proxy to Tor. Probably we should reserve a range of command values for use by commands like this where the transport proxy is reporting stuff to Tor that isn't in response to a command from Tor.
I decided to not include any statistics information in this version of the proposal. Let's do that as part of #5040 ASAP.
Inlining the updated proposal in my next mail.
I pushed an updated version of this proposal to a branch named 'bug4773' in 'https://git.gitorious.org/torspec/torspec.git'.
Inlining updated proposal:
Filename: xxx-transport-control-ports.txt Title: Extended ORPort and TransportControlPort Author: George Kadianakis, Nick Mathewson Created: 14 Mar 2012 Status: Open Target: 0.2.4.x
1. Overview
Proposal 180 defined Tor pluggable transports, a way to decouple protocol-level obfuscation from the core Tor protocol in order to better resist client-bridge censorship. This is achieved by introducing pluggable transport proxies, programs that obfuscate Tor traffic to resist DPI detection.
Proposal 180 defined a way for pluggable transport proxies to communicate with local Tor clients and bridges, so as to exchange traffic. This document extends this communication protocol, so that pluggable transport proxies can exchange arbitrary operational information and metadata with Tor clients and bridges.
2. Motivation
The communication protocol specified in Proposal 180 gives a way for transport proxies to announce the IP address of their clients to tor. Still, modern pluggable transports might have more (?) needs than this. For example:
1. Tor might want to inform pluggable transport proxies on how to rate-limit incoming or outgoing connections.
2. Server pluggable transport proxies might want to pass client information to an anti-active-probing system controlled by tor.
3. Tor might want to temporarily stop a transport proxy from obfuscating traffic.
To satisfy the above use cases, there must be real-time 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.
Specifically, transports proxies deliver each connection to the "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.
3. The new port protocols
3.1. The new extended ORPort protocol
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. The next bytes sent by the transport will be those tunneled over it. (body ignored)
[0x0001] USERADDR: an address:port string that represents the user's address.
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. The pluggable transport proxy must use the "identifier" to access the TransportControlPort. See the 'Association and identifier creation' section below.
Parties should ignore command codes that they do not understand.
3.2. The new TransportControlPort protocol
The TransportControlPort protocol is as follows:
CONNECTIONID[16 bytes, big-endian] COMMAND [2 bytes, big-endian] BODYLEN [2 bytes, big-endian] BODY [BODYLEN bytes]
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.
[0x0002] 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:
[0x1001] NOT_ALLOWED: Message notifying that the CONNECTIONID could not be matched with an authorized connection ID. The bridge SHOULD shutdown the connection.
[0x1001] RATE_LIMIT: Carries information on how the pluggable transport proxy should rate-limit its traffic. See the 'Rate Limiting' section below.
CONNECTIONID should carry the connection identifier described in the 'Association and identifier creation' section.
Parties should ignore command codes that they do not understand.
3.3. 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 MUST create its identifiers by generating 16 bytes of random data.
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 contain two integers, 4 bytes each, in big-endian format. The two numbers should represent the bandwidth rate and bandwidth burst respectively in 'bytes per second' which the transport proxy must set as its overall rate-limiting setting.
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 MAY 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 MAY want to shutdown its connections to the transport proxy.
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.
An attacker with superuser access, is able to sniff network traffic, and capture TransportControlPort identifiers and any data passed through those ports.
Tor SHOULD issue a warning if the bridge operator tries to bind Extended ORPort or TransportControlPort to a non-localhost address.
Pluggable transport proxies SHOULD issue a warning if they are instructed to connect to a non-localhost Extended ORPort or TransportControlPort.
6. Future
In the future, we might have pluggable transports which require the _client_ transport proxy to use the TransportControlPort and exchange control information with the Tor client. The current proposal doesn't yet support this, but we should not add functionality that will prevent it from being possible.
On Wed, Mar 14, 2012 at 5:18 PM, George Kadianakis desnacked@riseup.net wrote:
I pushed an updated version of this proposal to a branch named 'bug4773' in 'https://git.gitorious.org/torspec/torspec.git'.
Inlining updated proposal:
Filename: xxx-transport-control-ports.txt Title: Extended ORPort and TransportControlPort Author: George Kadianakis, Nick Mathewson Created: 14 Mar 2012 Status: Open Target: 0.2.4.x
Thanks! I have added this as proposal 196.