Hello,
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 PT implementation.
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 http://www.schwanenlied.me/yawning/obfsproxyssh-20130627.tar.gz
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 words). * 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).
Open questions: * 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? (Probably not.) * 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.
Regards,
On 28/06/13 10:13, Yawning Angel wrote:
Hello,
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 PT implementation.
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.
What sort of PKI are you using to verify the pubkey claimed by either side, to prevent MitM? SSL has the hierarchical PKI of X.509, whereas SSH does not have a "standard" PKI. Do you know about monkeysphere?
(Generally, I prefer SSH to SSL because it authenticates both ways by default. But you must have a good PKI in mind to prevent MitM.)
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 http://www.schwanenlied.me/yawning/obfsproxyssh-20130627.tar.gz
Great, please let us know when it's easier to use!
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 words).
- 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).
Open questions:
- 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?
(Probably not.)
- 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.
Regards,
On Tue, 02 Jul 2013 23:42:20 +0000, Ximin Luo wrote: ...
What sort of PKI are you using to verify the pubkey claimed by either side, to prevent MitM?
What for? The authentication happens in the next step, within the OR/bridge protocol. In this case we just have an additional layer of encryption around it.
Andreas
On 26 July 2013 23:56, Andreas Krey a.krey@gmx.de wrote:
On Tue, 02 Jul 2013 23:42:20 +0000, Ximin Luo wrote: ...
What sort of PKI are you using to verify the pubkey claimed by either side, to prevent MitM?
What for? The authentication happens in the next step, within the OR/bridge protocol. In this case we just have an additional layer of encryption around it.
I've always thought with SSH-based obsproxies, that you could distribute the SSH private key to connect to the server with the bridge IP address:port. Then, when a user connects to the bridge they use that SSH private key to login to SSH as normal (and then talk Tor, and authenticate the relay). If a scanner saw the connection and suspected it was Tor, they would try and connect, and be presented with the normal SSH login... which they couldn't complete because they don't know a valid username/password. They wouldn't be sure the server was running Tor then. If however the obsproxy accepted any SSH password/key, the scanner could successfully connect and determine it was running Tor.
So I think the value of requiring a login a the SSH-based obsproxy is not for authentication but for scanning resistance.
-tom
On Sat, 27 Jul 2013 09:52:52 +0000, Tom Ritter wrote: ...
I've always thought with SSH-based obsproxies, that you could distribute the SSH private key to connect to the server with the bridge IP address:port.
I couldn't quite avoid the reflexive cringe at 'distribute private key'. :-)
...
So I think the value of requiring a login a the SSH-based obsproxy is not for authentication but for scanning resistance.
Ah, that's a cool idea. I was already assuming that a specific key would be used to select the tor service on the sshd, but making that key variable is a nice twist. (I didn't know the bridgedb has space for such info.)
Andreas
On 2013-07-29 00:05, Andreas Krey wrote:
On Sat, 27 Jul 2013 09:52:52 +0000, Tom Ritter wrote: ...
I've always thought with SSH-based obsproxies, that you could distribute the SSH private key to connect to the server with the bridge IP address:port.
I couldn't quite avoid the reflexive cringe at 'distribute private key'. :-)
...
So I think the value of requiring a login a the SSH-based obsproxy is not for authentication but for scanning resistance.
Ah, that's a cool idea. I was already assuming that a specific key would be used to select the tor service on the sshd, but making that key variable is a nice twist. (I didn't know the bridgedb has space for such info.)
Yep, that's the idea. All of the arguments in the gigantic bridge line of doom are the equivalent of something like the shared secret component present in ScrambleSuit.
The code's changed quite a bit since I've last posted (per discussion with asn a while ago, we decided that it would be better to use a "real" ssh client), so I have been working on a python script that wraps OpenSSH. Works fairly well under U*IX, but under Windows, there's a few issues that need to be addressed still.
Regards,
On Fri, Jun 28, 2013 at 02:13:18AM -0700, Yawning Angel wrote:
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.
Is there a public server running this code that people can test against?
David Fifield