[tor-dev] RFC: obfsproxyssh
yawning at schwanenlied.me
Fri Jun 28 09:13:18 UTC 2013
I have been talking about this in #tor-dev for a while (and pestering
people with questions regarding some of the more nuanced aspects of
writing a pluggable transport, thanks to nickm, mikeperry and asn for
their help), and finally have what I would consider a pre-alpha for the
obfsproxyssh is a pluggable transport that uses the ssh wire protocol to
hide tor traffic. It uses libssh2 and interacts with a real sshd
located on the bridge side. Behaviorally it is identical to a user
sshing to a host, authenticating with a RSA public/private key pair and
opening a direct-tcp channel to the ORPort of the bridge.
It is more aimed at non-technical users (because anyone with an account
on a bridge can create a tunnel of their own using existing ssh
clients), and thus can be configured entirely through the torrc.
It still needs a bit of work before it is ready for deployment but the
code is at the point where I can use it for casual web browsing, so if
people are interested, I have put a snapshot online at
Note that it is still at the "I got it working today" state, so some
parts may be a bit rough around the edges, and more than likely a few
really dumb bugs lurk unseen.
Things that still need to be done (in rough order of priority):
* It needs to scrub IP addresses in logs.
* I need to compare libssh2's KEX phase with popular ssh clients (For
the initial "production" release more than likely Putty). It currently
also sends a rather distinctive banner since I'm not sure which
client(s) it will end up mimicking.
* I need to come up with a solution for server side sshd logs. What I
will probably end up doing is writing a patch for OpenSSH to disable
logging for select users.
* In a peculiar oversight, OpenSSH doesn't have a way to disable
reverse ssh tunnels (Eg: "PermitOpen 127.0.0.1:6969" allows clients to
listen on that port). Not a big deal if Tor starts up before any
clients connect, but I'll probably end up writing another patch for this.
* Someone needs to test it on Windows. All of my external dependencies
are known to work, so the porting effort should be minimal (Famous last
* The code needs to scrub the private key as soon as a connection
succeeds in authenticating instead of holding onto it. Probably not a
big deal since anyone that can look at the PT's heap can also look at
the bridge line in the torrc.
Nice to haves:
* Write real Makefiles instead of using CMake (I was lazy).
src/CMakeLists.txt currently needs to be edited for anyone compiling it.
* It currently uses unencrypted RSA keys. libssh2 supports ssh-agent
(on all of the relevant platforms) so key management can be handled that
way. I do not think there is currently a mechanism for Tor to query the
user for a passphrase and pass it to the PT, but if one gets added,
support it would also be easy from my end.
* The code does not handle IPv6 since it uses SOCKS 4 instead of 5.
When Tor gets a way to pass arguments to PTs that are > 510 bytes, I
will change this.
* libssh2 needs a few improvements going forward (In particular it does
not support ECDSA at all).
* Code for the bridge side that makes the tunnel speak the manged PT
server transport protocol would be nice (For rate limiting).
* libssh2_helpers.c should go away one day. Not sure why the libssh2
maintainers haven't merged the patch that I based the code in there on.
Things that need to be done on the Tor side of things:
* 0.2.4-14-alpha does not have the PT argument parsing code, so this
requires a build out of git to function.
* The code currently in Git fails to parse bridge lines with arguments
that can't be passed via SOCKS 5 (size restriction). The PT tarball has
a crude patch that removes the check, but the config file parser needs
to be changed.
* The Tor code currently in Git likes to forget PT arguments. asn was
kind enough to provide me with a patch that appears to fix this (though
the PT has a workaround for when it encounters this situation), but
moving forward a formal fix would be ideal.
* All the PT related cleverness in the world won't do much vs active
probing if there is an ORport exposed on the bridge. Tor should be able
to handle "ORPort 127.0.0.1:6969" (It may currently work, I'm not sure.
There should be a way to disable the reachability check if only to
reduce log spam).
* Is this useful?
* Is it worth biting the bullet and rewriting this to use Twisted Conch
instead of being a C app?
* Would it be simpler to write a wrapper around existing ssh clients?
* How should people handle distributing bridge information?
* How to handle the private key to a given bridge getting compromised?
(Correctly configured, all that someone who obtains the key would be
able to do is talk to the OR port so it's not a security thing, but it
opens the bridge to being blocked).
* Does Tor tunneled over SSH look distinctive? No effort is made to
change the traffic signature, though this can be added if needed.
The tarball contains a more detailed README explaining how to set it up
and how it works. obfsproxyssh_client.c has a more in-depth TODO list
as a large comment near the top of the file.
Comments and feedback will be appreciated.
More information about the tor-dev