Since #28942, Snowflake no longer uses the go-webrtc library. (Actually
server-webrtc still uses it, but server-webrtc itself is hardly used.) I
opened a ticket (at GitHub, where go-webrtc is hosted) to discuss what
to do with it, especially by third parties who may not know that its
maintainers aren't working on it actively any more.
https://github.com/keroserene/go-webrtc/issues/109
Hey, I started a pad for brainstorming ideas for GSoC projects here:
https://pad.riseup.net/p/anti-censorship-gsoc
I've copied over the project from last year. Feel free to edit, add or
reply to this thread.
Cecylia
Let's reconvene on Thursday, January 2nd. It will no longer be 2019, so
I created a new meeting pad for us and populated it with the content of
our old pad:
<https://pad.riseup.net/p/tor-anti-censorship-keep>
The old pad now also links to the new one.
Cheers,
Philipp
This week's meeting falls on Thanksgiving, a U.S. holiday, so several of
us won't be around. Let's cancel our Thursday meeting and meet again
next week, on December 4.
Cheers,
Philipp
Hi!
We need to work on roadmapping January and February, mostly for the
sponsor 28. Can you all meet on December 16th or 17th?
cheers,
gaba
--
Project Manager: Network, Anti-Censorship and Metrics teams
gaba at torproject.org
she/her are my pronouns
GPG Fingerprint EE3F DF5C AD91 643C 21BE 8370 180D B06C 59CA BD19
Other teams have started to use IRC keywords to reach team members,
e.g.: "network-team: somebody review #foo".
We discussed this in today's meeting and agreed to use both "ac-team"
and "anti-censorship-team" for our team:
<http://meetbot.debian.net/tor-meeting/2019/tor-meeting.2019-11-14-18.00.html>
Cheers,
Philipp
I posted this at https://github.com/net4people/bbs/issues/14#issuecomment-544747519
but it's relevant to anti-censorship in Tor.
Here are proof-of-concept branches implementing the turbo tunnel idea in
obfs4proxy, one using kcp-go/smux and one using quic-go:
* https://dip.torproject.org/dcf/obfs4/tree/reconnecting-kcp
* https://dip.torproject.org/dcf/obfs4/tree/reconnecting-quic
As diffs:
* [Changes needed to add kcp-go/smux to plain obfs4proxy](https://dip.torproject.org/dcf/obfs4/compare/aa7313b7eb78b7546a…
* [Changes needed to adapt kcp-go/smux to quic-go](https://dip.torproject.org/dcf/obfs4/compare/b5d6895542b8fce929739…
Using either of these branches, your circumvention session is decoupled
from any single TCP connection. If a TCP connection is terminated, the
obfs4proxy client will establish a new connection and pick up where it
left off. An error condition is signaled to the higher-level application
only when there's a problem establishing a new connection. Otherwise,
transient connection termination is invisible (except as a brief
increase in RTT) to Tor and whatever other application layers are being
tunnelled.
I did a small experiment showing how a Tor session can persist, despite
the obfs4 layer being interrupted every 20 seconds. I configured the
"little bastard" connection terminator to forward from a local port to a
remote bridge, and terminate connections after 20 seconds.
```
lilbastard$ cargo run -- -w 20 127.0.0.1:3000 192.81.135.242:4000
```
On the bridge, I ran tor using either plain obfs4proxy, or one of the
two turbo tunnel branches. (I did the experiment once for each of the
three configurations.)
```
DataDirectory datadir.server
SOCKSPort 0
ORPort auto
BridgeRelay 1
AssumeReachable 1
PublishServerDescriptor 0
ExtORPort auto
ServerTransportListenAddr obfs4 0.0.0.0:4000
ServerTransportPlugin obfs4 exec ./obfs4proxy -enableLogging -unsafeLogging -logLevel DEBUG
# ServerTransportPlugin obfs4 exec ./obfs4proxy.kcp -enableLogging -unsafeLogging -logLevel DEBUG
# ServerTransportPlugin obfs4 exec ./obfs4proxy.quic -enableLogging -unsafeLogging -logLevel DEBUG
```
On the client, I configured tor to use the corresponding obfs4proxy
executable, and connect to the bridge through the "little bastard"
proxy. (If you do this, your bridge fingerprint and cert will be
different.)
```
DataDirectory datadir.client
SOCKSPort 9250
UseBridges 1
Bridge obfs4 127.0.0.1:3000 94E4D617537C3E3CEA0D1D6D0BC852B5A7613B77 cert=6rB8kVd981U0G2b9nXioB5o0Zu7tDpDkoZyPe2aCmqFzGmfaSiNIfQvkJABakH+DfYwWRw iat-mode=0
ClientTransportPlugin obfs4 exec ./obfs4proxy -enableLogging -unsafeLogging -logLevel DEBUG
# ClientTransportPlugin obfs4 exec ./obfs4proxy.kcp -enableLogging -unsafeLogging -logLevel DEBUG
# ClientTransportPlugin obfs4 exec ./obfs4proxy.quic -enableLogging -unsafeLogging -logLevel DEBUG
```
Then, I captured traffic for 90 seconds while downloading a video file
through the tor proxy.
In the "plain obfs4proxy" case, the download stopped after the first
connection termination at 20 s. Every 20 s after that, there was a small
amount of activity, which was tor reconnecting to the bridge (and the
resulting obfs4 handshake). But it didn't matter, because tor has
already signaled the first connection termination to the application
layer, which gave up:
```
curl: (18) transfer closed with 111535615 bytes remaining to read
```
In comparison, the "kcp" and "quic" cases kept on downloading, being
only momentarily delayed by a connection termination.
Notes:
* How this works architecturally, on the client side, we replace the
original TCP Dial call with either kcp.NewConn2 or quic.Dial, over an
abstract packet-sending interface (clientPacketConn).
clientPacketConn runs a loop that repeatedly connects to the same
destination and exchanges packets (represented as length-prefixed
blobs in a TCP stream) as long as the connection is good, reporting
an error only when a connection attempt fails. On the server side, we
replace the TCP Listen call with either kcp.ServeConn or quic.Listen,
over an abstract serverPacketConn. serverPacketConn opens a single
TCP listener, takes length-prefixed packets from *all* the TCP
streams that arrive at the listener, and feeds them into a *single*
KCP or QUIC engine. Whenever we need to send a packet for a
particular connection ID, we send it on the TCP stream that most
recently sent us a packet for that connection ID.
* There's no need for this functionality to be built into obfs4proxy
itself. It could be done as a separate program:
```
------------ client ------------ ------------ bridge ------------
tor -> turbotunnel -> obfs4proxy -> internet -> obfs4proxy -> turbotunnel -> tor
```
But this kind of process layering is cumbersome with pluggable transports.
* I'm passing a blank client IP address to the pt.DialOr call—this
information is used for geolocation in Metrics graphs. That's because
an OR connection no longer corresponds to a single incoming IP
address with its single IP address—instead it corresponds to an
abstract "connection ID" that remains constant across potentially
many TCP connections. In order to make this work, you would have to
define some heuristic such as "the client IP address associated with
the OR connection is that of the first TCP connection that carried
that connection ID."