[tor-dev] Fwd: Tor Transports
kmacy at freebsd.org
Sat Jan 21 19:09:58 UTC 2012
I felt it premature to publicly discuss using my user level network
stack as the basis for a tor transport given the number of potential
candidates and the issues that I raise below. However, Sebastian felt
strongly that it belongs on tor-dev.
---------- Forwarded message ----------
From: K. Macy <kmacy at freebsd.org>
Date: Sat, Jan 21, 2012 at 3:05 PM
Subject: Re: Tor Transports
On Fri, Jan 20, 2012 at 11:35 PM, Steven Murdoch
<Steven.Murdoch at cl.cam.ac.uk> wrote:
> Hi All,
> One hop-by-hop transport protocol we will likely be considering for an alternative Tor transport is TCP, and Kip Macy (a FreeBSD developer, Cc'd) has been working on porting the FreeBSD network stack to userspace, with the Tor use-case in mind. Unlike many other attempts though, maintainability has been a primary concern, so we should be able to keep in sync with the FreeBSD stack with manageable effort.
> Another advantage of this approach is that we will get IPSec for free, which could be very useful if we decide DTLS is not the way to go.
> The FreeBSD network stack is extremely well tested, so we are in a good position from that respect. One downside is that the code size might be large (unless we can find a way to do some clever link-time optimization away of dead code).
> His code is here: http://gitorious.org/~kmm/freebsd/kmm-sandbox/commits/work/svn_trunk_libplebnet
It obviously also supports SCTP to whatever extent that FreeBSD does.
The author of the RFCs and of the reference SCTP stack on all
operating systems except Linux is a FreeBSD committer. Another reason
why I chose to take this approach is you get all of the kernel
firewall bits "for free." Thus one could envision supporting
transparent proxying in the application itself to allow for
transparent Tor usage in an OS independent manner.
I have a few additional comments to add to set expectations appropriately.
1) I have a prototype "safe" BPF API whereby an unprivileged
application can only receive and send packets on a single or
pre-specified set of IP addresses and only advertise its private
stack's MAC address. Without this functionality one needs to either
layer the stack on top of kernel UDP (perfectly reasonable approach,
just requires writing another simple virtual NIC driver) or running as
root, whereby plebeian networking becomes a misnomer - a patrician
poseur as it were. Having even such a simple kernel module goes
against the grain of Tor conventions of not doing anything as root
(although configuring things like transparent proxying require a
certain amount of futzing as root).
2) The libc shim is written with the idea that it overrides the
relevant libc symbols by means of LD_PRELOAD. The library
differentiates between "kernel descriptors" for files, unix sockets,
or anything outside the scope of the network stack and "user
descriptors". For example, when a kernel descriptor is passed to
write() libplebnet will call _write() with the arguments and the call
should functional as it normally does.
3) At this instant libplebnet does not support localhost communication
over TCP/UDP. I believe that the most efficient way of supporting this
would be by means of directing those packets to a tap device.
3) Without a (most likely) substantial amount of work to share user
level network state across address spaces, the apache style
(pre-)forked process with shared accept socket does not work. I have
not given it any thought as I don't see a use case for it.
4) Stack configuration was, to my surprise at least, the biggest
hurdle. The UNIX APIs for configuring network stack state are anything
but user friendly. To enable continued use of the standard tools
(ifconfig, route, arp, etc) I wrote a separate library called
libplebconf which one would LD_PRELOAD with the pid of the the process
to be configured set as an environment variable. At startup libplebnet
creates a thread which listens on a unix socket at "/tmp/<pid>" and
accepts as messages serialized system calls to the various
configuration calls that the aforementioned programs use. To simplify
things a bit I've added an additional environment variable with the
path to an rc.conf which gets executed at startup to configure the
process using libplebnet's ip and route.
Most of this will be moot in the event that you choose to cut out
layer 3 and interface directly between your L4 of choice and DTLS. I
haven't given any thought to how to eliminate this complexity in the
event that you choose to use FreeBSD's IPSEC.
To avoid boring most readers I have kept the discussion rather
superficial. Nonetheless, I hope that this missive clarifies matters
more than it confuses them.
More information about the tor-dev