mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-26 15:42:34 +01:00
306 lines
13 KiB
Text
306 lines
13 KiB
Text
Filename: xxx-pluggable-transport.txt
|
|
Title: Pluggable transports for circumvention
|
|
Author: Jacob Appelbaum, Nick Mathewson
|
|
Created: 15-Oct-2010
|
|
Status: Draft
|
|
|
|
Overview
|
|
|
|
This proposal describes a way to decouple protocol-level obfuscation
|
|
from the core Tor protocol in order to better resist client-bridge
|
|
censorship. Our approach is to specify a means to add pluggable
|
|
transport implementations to Tor clients and bridges so that they can
|
|
negotiate a superencipherment for the Tor protocol.
|
|
|
|
Scope
|
|
|
|
This is a document about transport plugins; it does not cover
|
|
discovery improvements, or bridgedb improvements. While these
|
|
requirements might be solved by a program that also functions as a
|
|
transport plugin, this proposal only covers the requirements and
|
|
operation of transport plugins.
|
|
|
|
Motivation
|
|
|
|
Frequently, people want to try a novel circumvention method to help
|
|
users connect to Tor bridges. Some of these methods are already
|
|
pretty easy to deploy: if the user knows an unblocked VPN or open
|
|
SOCKS proxy, they can just use that with the Tor client today.
|
|
|
|
Less easy to deploy are methods that require participation by both the
|
|
client and the bridge. In order of increasing sophistication, we
|
|
might want to support:
|
|
|
|
1. A protocol obfuscation tool that transforms the output of a TLS
|
|
connection into something that looks like HTTP as it leaves the
|
|
client, and back to TLS as it arrives at the bridge.
|
|
2. An additional authentication step that a client would need to
|
|
perform for a given bridge before being allowed to connect.
|
|
3. An information passing system that uses a side-channel in some
|
|
existing protocol to convey traffic between a client and a bridge
|
|
without the two of them ever communicating directly.
|
|
4. A set of clients to tunnel client->bridge traffic over an existing
|
|
large p2p network, such that the bridge is known by an identifier
|
|
in that network rather than by an IP address.
|
|
|
|
We could in theory support these almost fine with Tor as it stands
|
|
today: every Tor client can take a SOCKS proxy to use for its outgoing
|
|
traffic, so a suitable client proxy could handle the client's traffic
|
|
and connections on its behalf, while a corresponding program on the
|
|
bridge side could handle the bridge's side of the protocol
|
|
transformation. Nevertheless, there are some reasons to add support
|
|
for transportation plugins to Tor itself:
|
|
|
|
1. It would be good for bridges to have a standard way to advertise
|
|
which transports they support, so that clients can have multiple
|
|
local transport proxies, and automatically use the right one for
|
|
the right bridge.
|
|
|
|
2. There are some changes to our architecture that we'll need for a
|
|
system like this to work. For testing purposes, if a bridge blocks
|
|
off its regular ORPort and instead has an obfuscated ORPort, the
|
|
bridge authority has no way to test it. Also, unless the bridge
|
|
has some way to tell that the bridge-side proxy at 127.0.0.1 is not
|
|
the origin of all the connections it is relaying, it might decide
|
|
that there are too many connections from 127.0.0.1, and start
|
|
paring them down to avoid a DoS.
|
|
|
|
3. Censorship and anticensorship techniques often evolve faster than
|
|
the typical Tor release cycle. As such, it's a good idea to
|
|
provide ways to test out new anticensorship mechanisms on a more
|
|
rapid basis.
|
|
|
|
4. Transport obfuscation is a relatively distinct problem
|
|
from the other privacy problems that Tor tries to solve, and it
|
|
requires a fairly distinct skill-set from hacking the rest of Tor.
|
|
By decoupling transport obfuscation from the Tor core, we hope to
|
|
encourage people working on transport obfuscation who would
|
|
otherwise not be interested in hacking Tor.
|
|
|
|
5. Finally, we hope that defining a generic transport obfuscation plugin
|
|
mechanism will be useful to other anticensorship projects.
|
|
|
|
Non-Goals
|
|
|
|
We're not going to talk about automatic verification of plugin
|
|
correctness and safety via sandboxing, proof-carrying code, or
|
|
whatever.
|
|
|
|
We need to do more with discovery and distribution, but that's not
|
|
what this proposal is about. We're pretty convinced that the problems
|
|
are sufficiently orthogonal that we should be fine so long as we don't
|
|
preclude a single program from implementing both transport and
|
|
discovery extensions.
|
|
|
|
This proposal is not about what transport plugins are the best ones
|
|
for people to write. We do, however, make some general
|
|
recommendations for plugin authors in an appendix.
|
|
|
|
We've considered issues involved with completely replacing Tor's TLS
|
|
with another encryption layer, rather than layering it inside the
|
|
obfuscation layer. We describe how to do this in an appendix to the
|
|
current proposal, though we are not currently sure whether it's a good
|
|
idea to implement.
|
|
|
|
We deliberately reject any design that would involve linking more code
|
|
into Tor's process space.
|
|
|
|
Design overview
|
|
|
|
To write a new transport protocol, an implementer must provide two
|
|
pieces: a "Client Proxy" to run at the initiator side, and a "Server
|
|
Proxy" to run a the server side. These two pieces may or may not be
|
|
implemented by the same program.
|
|
|
|
Each client may run any number of Client Proxies. Each one acts like
|
|
a SOCKS proxy that accepts accept connections on localhost. Each one
|
|
runs on a different port, and implements one or more transport
|
|
methods. If the protocol has any parameters, they passed from Tor
|
|
inside the regular username/password parts of the SOCKS protocol.
|
|
|
|
Bridges (and maybe relays) may run any number of Server Proxies: these
|
|
programs provide an interface like stunnel-server (or whatever the
|
|
option is): they get connections from the network (typically by
|
|
listening for connections on the network) and relay them to the
|
|
Bridge's real ORPort.
|
|
|
|
To configure one of these programs, it should be sufficient simply to
|
|
list it in your torrc. The program tells Tor which transports it
|
|
provides.
|
|
|
|
Bridges (and maybe relays) report in their descriptors which transport
|
|
protocols they support. This information can be copied into bridge
|
|
lines. Bridges using a transport protocol may have multiple bridge
|
|
lines.
|
|
|
|
Any methods that are wildly successful, we can bake into Tor.
|
|
|
|
Specifications: Client behavior
|
|
|
|
Bridge lines can now follow the extended format "bridge method
|
|
address:port [[keyid=]id-fingerprint] [k=v] [k=v] [k=v]". To connect
|
|
to such a bridge, a client must open a local connection to the SOCKS
|
|
proxy for "method", and ask it to connect to address:port. If
|
|
[id-fingerprint] is provided, it should expect the public identity key
|
|
on the TLS connection to match the digest provided in
|
|
[id-fingerprint]. If any [k=v] items are provided, they are
|
|
configuration parameters for the proxy: Tor should separate them with
|
|
NUL bytes and put them user and password fields of the request,
|
|
splitting them across the fields as necessary. The "id-fingerprint"
|
|
field is always provided in a field named "keyid", if it was given.
|
|
|
|
Example: if the bridge line is "bridge trebuchet www.example.com:3333
|
|
rocks=20 height=5.6m" AND if the Tor client knows that the
|
|
'trebuchet' method is provided by a SOCKS5 proxy on
|
|
127.0.0.1:19999, the client should connect to that proxy, ask it to
|
|
connect to www.example.com, and provide the string
|
|
"rocks=20\0height=5.6m" as the username, the password, or split
|
|
across the username and password.
|
|
|
|
There are two ways to tell Tor clients about protocol proxies:
|
|
external proxies and managed proxies. An external proxy is configured
|
|
with "ClientTransportPlugin trebuchet socks5 127.0.0.1:9999". This
|
|
tells Tor that another program is already running to handle
|
|
'trubuchet' connections, and Tor doesn't need to worry about it. A
|
|
managed proxy is configured with "ClientTransportPlugin trebuchet
|
|
/usr/libexec/tor-proxies/trebuchet [options]", and tells Tor to launch
|
|
an external program on-demand to provide a socks proxy for 'trebuchet'
|
|
connections. The Tor client only launches one instance of each
|
|
external program, even if the same executable is listed for more than
|
|
one method.
|
|
|
|
The same program can implement a managed or an external proxy: it just
|
|
needs to take an argument saying which one to be.
|
|
|
|
Client proxy behavior
|
|
|
|
When launched from the command-line by a Tor client, a transport
|
|
proxy needs to tell Tor which methods and ports it supports. It does
|
|
this by printing one or more CMETHOD: lines to its stdout. These look
|
|
like
|
|
|
|
CMETHOD: trebuchet SOCKS5 127.0.0.1:19999 ARGS:rocks,height \
|
|
OPT-ARGS:tensile-strength
|
|
|
|
The ARGS field lists mandatory parameters that must appear in every
|
|
bridge line for this method. The OPT-ARGS field lists optional
|
|
parameters. If no ARGS or OPT-ARGS field is provided, Tor should not
|
|
check the parameters in bridge lines for this method.
|
|
|
|
The proxy should print a single "METHODS:DONE" line after it is
|
|
finished telling Tor about the methods it provides.
|
|
|
|
The transport proxy MUST exit cleanly when it receives a SIGTERM from
|
|
Tor.
|
|
|
|
The Tor client MUST ignore lines beginning with a keyword and a colon
|
|
if it does not recognize the keyword.
|
|
|
|
In the future, if we need a control mechanism, we can use the
|
|
stdin/stdout from Tor to the transport proxy.
|
|
|
|
A transport proxy MUST handle SOCKS connect requests using the SOCKS
|
|
version it advertises.
|
|
|
|
Tor clients SHOULD NOT use any method from a client proxy unless it
|
|
is both listed as a possible method for that proxy in torrc, and it
|
|
is listed by the proxy as a method it supports.
|
|
|
|
[XXXX say something about versioning.]
|
|
|
|
Server behavior
|
|
|
|
Server proxies are configured similarly to client proxies.
|
|
|
|
|
|
|
|
Server proxy behavior
|
|
|
|
|
|
|
|
[so, we can have this work like client proxies, where the bridge
|
|
launches some programs, and they tell the bridge, "I am giving you
|
|
method X with parameters Y"? Do you have to take all the methods? If
|
|
not, which do you specify?]
|
|
|
|
[Do we allow programs that get started independently?]
|
|
|
|
[We'll need to figure out how this works with port forwarding. Is
|
|
port forwarding the bridge's problem, the proxy's problem, or some
|
|
combination of the two?]
|
|
|
|
[If we're using the bridge authority/bridgedb system for distributing
|
|
bridge info, the right place to advertise bridge lines is probably
|
|
the extrainfo document. We also need a way to tell the bridge
|
|
authority "don't give out a default bridge line for me"]
|
|
|
|
Server behavior
|
|
|
|
Bridge authority behavior
|
|
|
|
Implementation plan
|
|
|
|
Turn this into a draft proposal
|
|
|
|
Circulate and discuss on or-dev.
|
|
|
|
We should ship a couple of null plugin implementations in one or two
|
|
popular, portable languages so that people get an idea of how to
|
|
write the stuff.
|
|
|
|
1. We should have one that's just a proof of concept that does
|
|
nothing but transfer bytes back and forth.
|
|
|
|
1. We should not do a rot13 one.
|
|
|
|
2. We should implement a basic proxy that does not transform the bytes at all
|
|
|
|
1. We should implement DNS or HTTP using other software (as goodell
|
|
did years ago with DNS) as an example of wrapping existing code into
|
|
our plugin model.
|
|
|
|
2. The obfuscated-ssh superencipherment is pretty trivial and pretty
|
|
useful. It makes the protocol stringwise unfingerprintable.
|
|
|
|
1. Nick needs to be told firmly not to bikeshed the obfuscated-ssh
|
|
superencipherment too badly
|
|
|
|
1. Go ahead, bikeshed my day
|
|
|
|
1. If we do a raw-traffic proxy, openssh tunnels would be the logical choice.
|
|
|
|
Appendix: recommendations for transports
|
|
|
|
Be free/open-source software. Also, if you think your code might
|
|
someday do so well at circumvention that it should be implemented
|
|
inside Tor, it should use the same license as Tor.
|
|
|
|
Use libraries that Tor already requires. (You can rely on openssl and
|
|
libevent being present if current Tor is present.)
|
|
|
|
Be portable: most Tor users are on Windows, and most Tor developers
|
|
are not, so designing your code for just one of these platforms will
|
|
make it either get a small userbase, or poor auditing.
|
|
|
|
Think secure: if your code is in a C-like language, and it's hard to
|
|
read it and become convinced it's safe then, it's probably not safe.
|
|
|
|
Think small: we want to minimize the bytes that a Windows user needs
|
|
to download for a transport client.
|
|
|
|
Specify: if you can't come up with a good explanation
|
|
|
|
Avoid security-through-obscurity if possible. Specify.
|
|
|
|
Resist trivial fingerprinting: There should be no good string or regex
|
|
to search for to distinguish your protocol from protocols permitted by
|
|
censors.
|
|
|
|
Imitate a real profile: There are many ways to implement most
|
|
protocols -- and in many cases, most possible variants of a given
|
|
protocol won't actually exist in the wild.
|
|
|
|
Appendix: Raw-traffic transports
|
|
|
|
This section describes an optional extension to the proposal above.
|
|
We are not sure whether it is a good idea.
|