1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
|
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. The Tor consensus should carry a new approved version number that
is specific for pluggable transport; this will allow Tor to know when a
particular transport is known to be unsafe safe or non-functional.
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
semicolons and put them user and password fields of the request,
splitting them across the fields as necessary. If a key or value
value must contain a semicolon or a backslash, it is escaped with a
backslash.
The "id-fingerprint" field is always provided in a field named
"keyid", if it was given. Method names must be C identifiers.
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;height=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
exec /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.
|