George,
I'd like to write a dns transport... and it seems to me the obfsproxy api isn't designed for non tcp transports... Maybe we again make some changes to the obfsproxy api? It would transport IP packets using a tun device... we can route it to a socks endpoint and proxy from there.
I think there is a whole class of obfuscated transports that could benefit from an obfsproxy plugin interface for vpns... transports that use a tun interface...
I'll have to take a closer look at the obfsproxy api and think about this some more. I was just curious to see if you had any thoughts on the subject.
There is this interesting code to learn about dns transport here: https://code.google.com/p/dnscapy/ it uses the scapy automatom api instead of twisted. Could easily be ported to twisted I think.
Feel free to forward your response to the tor-dev mailing list. No hurry. No worry.
Cheers!
David
Hello David!
I won't be able to answer thoroughly atm since I'm at the dev meeting. I will be back home soon and be able to answer more smoothly.
In general, a DNS transport would be great! A well designed DNS transport would be a PITA to block and would also work in most networks (even through captive portals etc.).
The short answer is that obfsproxy is indeed not designed to facilitate PTs like DNS transports. It will probably require a considerable refactor of obfsproxy to write a DNS pluggable transport. It will probably require so much refactoring that I'm not sure if it would make sense to merge the changes back upstream (because the changes might not be useful for other PTs).
The main reason you want to use obfsproxy is so that you don't have to write your own SOCKS code, or your own Extended ORPort code, or your own PT-protocol code.
That said, here are two other approaches you can take:
a) You can "fork" obfsproxy, perform your changes, and then we can deploy your fork as a standalone PT. Since obfsproxy's architecture is designed to support multiple PTs you might have to perform considerable changes to obfsproxy; but that's fine, since you will be the only one using that fork of obfsproxy.
A small problem with this approach is that we will have to deploy two obfsproxy codebases which will increase the size of the bundle. The good news is that the size of the obfsproxy codebase in the latest TBBs prepared by David is only 350Kb which is not too much even if doubled.
b) You can write your own Python code and selectively steal code from obfsproxy. You will have to steal the code that does networking, Extended ORPort, environment variable parsing (pyptlib), SOCKS, etc. This might not be too hard.
Alternatively you can use Go, and use David's goptlib library [0] which does both Extended ORPort and SOCKS.
Also, before you start writing code, it might be worth looking at the pt-spec and seeing if it can support DNS PTs as it is.
BTW, do you know of any censorship circumvention tools that use DNS as a covert channel?
[0]: https://gitweb.torproject.org/pluggable-transports/goptlib.git
George Kadianakis:
b) You can write your own Python code and selectively steal code from obfsproxy. You will have to steal the code that does networking, Extended ORPort, environment variable parsing (pyptlib), SOCKS, etc. This might not be too hard.
Could the shared code be used to augment pyptlib? I guess Extended ORPort is probably something that all Python pluggable transport implementations might want.
George Kadianakis:
b) You can write your own Python code and selectively steal code from obfsproxy. You will have to steal the code that does networking, Extended ORPort, environment variable parsing (pyptlib), SOCKS, etc. This might not be too hard.
Could the shared code be used to augment pyptlib? I guess Extended ORPort is probably something that all Python pluggable transport implementations might want.
The issue is that by adding an Extended ORPort implementation in pyptlib we would have to select a specific networking library (socket, Twisted, etc.) and the transport author would be forced to use the same networking library.
Of course, we could bypass this by coding Extended ORPort clients in multiple languages, or by just coding it in Twisted and letting the transport author simply not use if she doesn't want to. For example, goptlib has an Extended ORPort implementation using the default Go net lib.
On Wed, Feb 19, 2014 at 04:59:05PM -0800, George Kadianakis wrote:
George Kadianakis:
b) You can write your own Python code and selectively steal code from obfsproxy. You will have to steal the code that does networking, Extended ORPort, environment variable parsing (pyptlib), SOCKS, etc. This might not be too hard.
Could the shared code be used to augment pyptlib? I guess Extended ORPort is probably something that all Python pluggable transport implementations might want.
The issue is that by adding an Extended ORPort implementation in pyptlib we would have to select a specific networking library (socket, Twisted, etc.) and the transport author would be forced to use the same networking library.
It's not so clear what the best way to handle it is. We thought about it in the past but didn't come to a clear solution.
If any kind of ExtORPort support is added to pyptlib, I think it makes sense for it to be a Twisted one, because that's what people seem to want to use.
The act of creating a new transport program separate from obfsproxy, that steals as much code from obfsproxy as it needs, could be a good way to identify what ExtORPort functions need to be present in a library and how they need to be generalized. I think it would not be a waste of effort to make a new program with this goal in mind.
golang gets to cheat on the issue because there's really only one way to do concurrent networking in Go. (But also, nobody has used goptlib as much as I have, so it might not be as clear-cut as I think.)
David Fifield
I was thinking that a generalized mechanism for using vpns as obfsproxy transports would help solve for a dns transport... since a dns transport is going to use a tun device. Perhaps obfsproxy/network/launch_transport.py can be changed so that it has a vpn role... where it sets up the tun device and routes an address to that tun device... and then either binds + listens to a particular port (server) or connects to the ip address which is routed over the tun device (client). Obfsproxy in this mode would pass the data straight through like the dummy transport... and the vpn handling the tun device (could either be in the same twisted process or another forked process) takes care of obfuscating the tcp stream by passing the raw ip packets into dns queries etc.
On Thu, Feb 20, 2014 at 2:37 AM, David Fifield david@bamsoftware.com wrote:
On Wed, Feb 19, 2014 at 04:59:05PM -0800, George Kadianakis wrote:
George Kadianakis:
b) You can write your own Python code and selectively steal code from obfsproxy. You will have to steal the code that does networking, Extended ORPort, environment variable parsing (pyptlib), SOCKS, etc. This might not be too hard.
Could the shared code be used to augment pyptlib? I guess Extended ORPort is probably something that all Python pluggable transport implementations might want.
The issue is that by adding an Extended ORPort implementation in pyptlib we would have to select a specific networking library (socket, Twisted, etc.) and the transport author would be forced to use the same networking library.
It's not so clear what the best way to handle it is. We thought about it in the past but didn't come to a clear solution.
If any kind of ExtORPort support is added to pyptlib, I think it makes sense for it to be a Twisted one, because that's what people seem to want to use.
The act of creating a new transport program separate from obfsproxy, that steals as much code from obfsproxy as it needs, could be a good way to identify what ExtORPort functions need to be present in a library and how they need to be generalized. I think it would not be a waste of effort to make a new program with this goal in mind.
golang gets to cheat on the issue because there's really only one way to do concurrent networking in Go. (But also, nobody has used goptlib as much as I have, so it might not be as clear-cut as I think.)
David Fifield _______________________________________________ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Hello David and George and other people who are interested in there being even more obfuscation transports for tor, I appreciate the thought of making a frankenstein butchering of obfsproxy code which transports tor over dns... and speaks socks and tor control port... and works to PT spec... but what do you think about this:
With a relatively small code change it would be possible to make a pluggable system to get obfsproxy to use an external vpn as a bridge transport... Then we can write lots of fun simple vpn transports that spray different kinds of packets... tor over dns being one of the more interesting possible vpn transports... but perhaps tor over icmp would prove useful because nat traversal would be possible... whereas tor over bidirectional syn flood not so much. ;-)
When I again looked at pyobfsproxy.py, obfsproxy/managed/server.py, obfsproxy/managed/client.py and obfsproxy/transports/transports.py it occurred to me that we could parse an extra commandline arg to set obfsproxy into vpn mode... calling do_managed_server() and do_managed_client() with an optional keyword arg to set it to vpn mode wherein launch_transport_listener is called in either "vpnclient" or "vpnserver" mode... it looks at the transport options and creates a tun device and perhaps sets the ip to the address specified in the transport options, sets a static route to the run device, etc... Some other process or other reactor listener handles the vpn traffic by reading and writing to the tun device and spraying packets. Looking at launch_transport.py we see that launch_transport_listener would have to change a bit to handle the case where in vpn mode the downstream circuits for both server and client is over the tun device... In vpn mode obfsproxy just proxies over the tun device... and all the obfuscation is handled by the vpn program handling that tun device.
I was thinking that perhaps my pony's [1] twisted producer/consumer tun device classes might be useful in making various VPNs suitable to obfuscate tor traffic... the dns vpn being one of the more useful and interesting packet transports.
[1] - https://github.com/david415/ponyVPN/blob/master/tun_writer.py https://github.com/david415/ponyVPN/blob/master/tun_reader.py
Isis, George, what do you think of these client and server's torrc files for a dns vpn tor bridge? Do tor bridges have to be advertized with a ip:port? I think they do... for tor dns bridges this host and port won't be used... The tor dns bridge operator might want to advertize various transport options that help client's talk to their vpn transport... Given that we have some obfuscation vpn that sprays packets in whatever protocol... (dns, icmp, syn flood ;-)...) I was thinking... a tor client connecting to a tor dns bridge might have a torrc that looks like this.
--->
Log notice stdout SocksPort 8040 DataDirectory ./client-data UseBridges 1v Bridge vpn-ponydns 127.0.0.1:4703 tundevice=tun0 tun_local_ip=10.9.6.1 tun_remote_ip=10.9.6.2 tun_netmask=255.255.255.0 dns_name=my.cute.pony.bridge.dns_root ClientTransportPlugin vpn-ponydns exec /usr/local/bin/obfsproxy --log-min-severity=info --log-file=/var/log/tor/dawuud-obfsproxy/obfsproxy client.log --role=vpnclient managed
..< and the obfsproxy bridge server torrc like this:
Log notice stdout SocksPort 0 ORPort 7001 ExitPolicy reject *:* DataDirectory ./bridge-data
BridgeRelay 1 PublishServerDescriptor 0
ServerTransportListenAddr vpn-ponydns 127.0.0.1:4703
ServerTransportPlugin vpn-ponydns exec /usr/local/bin/obfsproxy --log-min-severity=info --log-file=/var/log/tor/obfsproxy/obfsproxy-bridge.log --role=vpnserver managed ServerTransportOptions vpn-ponydns tundevice=tun0 tun_local_ip=10.9.6.2 tun_remote_ip=10.9.6.1 tun_netmask=255.255.255.0 dns_name=my.cute.pony.bridge.dns_root
~-~
On Wed, Feb 19, 2014 at 06:37:48PM -0800, David Fifield wrote:
On Wed, Feb 19, 2014 at 04:59:05PM -0800, George Kadianakis wrote:
George Kadianakis:
b) You can write your own Python code and selectively steal code from obfsproxy. You will have to steal the code that does networking, Extended ORPort, environment variable parsing (pyptlib), SOCKS, etc. This might not be too hard.
Could the shared code be used to augment pyptlib? I guess Extended ORPort is probably something that all Python pluggable transport implementations might want.
The issue is that by adding an Extended ORPort implementation in pyptlib we would have to select a specific networking library (socket, Twisted, etc.) and the transport author would be forced to use the same networking library.
It's not so clear what the best way to handle it is. We thought about it in the past but didn't come to a clear solution.
If any kind of ExtORPort support is added to pyptlib, I think it makes sense for it to be a Twisted one, because that's what people seem to want to use.
The act of creating a new transport program separate from obfsproxy, that steals as much code from obfsproxy as it needs, could be a good way to identify what ExtORPort functions need to be present in a library and how they need to be generalized. I think it would not be a waste of effort to make a new program with this goal in mind.
golang gets to cheat on the issue because there's really only one way to do concurrent networking in Go. (But also, nobody has used goptlib as much as I have, so it might not be as clear-cut as I think.)
David Fifield _______________________________________________ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
We technically don't need to use a tun device for the dns transport... but if a tun device is used for the tor dns transport then we get the reliability layer without having to write it ourselves. It doesn't matter that tun devices are lossy and udp is unreliable; we just spray packets. Obfsproxy has it's transport's circuit.downstream tcp connection routed over the tun device; tcp takes care of congestion control, retransmission etc.
I think it might also be useful to get a simple udp vpn working as an obfsproxy transport... it could listen on various ports... including udp port 53 which is sometimes accessible from within captive portals... and would be much faster than tunneling over dns. Quicktun http://wiki.ucis.nl/QuickTun seems like a sufficiently simple and cool (uses nacl's curve25519xsalsa20poly1305 crypto-box) vpn that might work well with an obfsproxy vpn plugin system... i kinda like how it's crypto can be turned off so that it passes the raw data over udp ;-)
It also seems like it would be easy to combine any existing obfsproxy transports with the obfsproxy vpn mode.... by having an existing obfsproxy transport class obfuscate the payload before passing it to the circuit's downstream tcp connection which is routed over the tun device.
Here's a few vpn + transport combinations that might be interesting: dns(udp-tun(ip(tcp(tor)))) dns(udp-tun(ip(tcp(bananaphone(tor))))) udp-quicktun-nacltai(ip(tcp(tor))) udp-quicktun-raw(ip(tcp(scramblesuit(tor)))) dns(udp-tun(ip(tcp(scramblesuit(tor)))))
George,
I'd like to write a dns transport... and it seems to me the obfsproxy api isn't designed for non tcp transports... Maybe we again make some changes to the obfsproxy api? It would transport IP packets using a tun device... we can route it to a socks endpoint and proxy from there.
I think there is a whole class of obfuscated transports that could benefit from an obfsproxy plugin interface for vpns... transports that use a tun interface...
I'll have to take a closer look at the obfsproxy api and think about this some more. I was just curious to see if you had any thoughts on the subject.
There is this interesting code to learn about dns transport here: https://code.google.com/p/dnscapy/ it uses the scapy automatom api instead of twisted. Could easily be ported to twisted I think.
Feel free to forward your response to the tor-dev mailing list. No hurry. No worry.
Cheers!
David
Hello David!
I won't be able to answer thoroughly atm since I'm at the dev meeting. I will be back home soon and be able to answer more smoothly.
In general, a DNS transport would be great! A well designed DNS transport would be a PITA to block and would also work in most networks (even through captive portals etc.).
The short answer is that obfsproxy is indeed not designed to facilitate PTs like DNS transports. It will probably require a considerable refactor of obfsproxy to write a DNS pluggable transport. It will probably require so much refactoring that I'm not sure if it would make sense to merge the changes back upstream (because the changes might not be useful for other PTs).
The main reason you want to use obfsproxy is so that you don't have to write your own SOCKS code, or your own Extended ORPort code, or your own PT-protocol code.
That said, here are two other approaches you can take:
a) You can "fork" obfsproxy, perform your changes, and then we can deploy your fork as a standalone PT. Since obfsproxy's architecture is designed to support multiple PTs you might have to perform considerable changes to obfsproxy; but that's fine, since you will be the only one using that fork of obfsproxy.
A small problem with this approach is that we will have to deploy two obfsproxy codebases which will increase the size of the bundle. The good news is that the size of the obfsproxy codebase in the latest TBBs prepared by David is only 350Kb which is not too much even if doubled.
b) You can write your own Python code and selectively steal code from obfsproxy. You will have to steal the code that does networking, Extended ORPort, environment variable parsing (pyptlib), SOCKS, etc. This might not be too hard.
Alternatively you can use Go, and use David's goptlib library [0] which does both Extended ORPort and SOCKS.
Also, before you start writing code, it might be worth looking at the pt-spec and seeing if it can support DNS PTs as it is.
BTW, do you know of any censorship circumvention tools that use DNS as a covert channel?
FWIW, people told me that Freenet has had a DNS transport for ages. There is also this: https://lists.torproject.org/pipermail/tor-talk/2006-January/007124.html
On Wed, Feb 19, 2014 at 05:00:09PM -0800, George Kadianakis wrote:
FWIW, people told me that Freenet has had a DNS transport for ages. There is also this: https://lists.torproject.org/pipermail/tor-talk/2006-January/007124.html
We had a little bit of brainstorming on a DNS transport on the PluggableTransports wiki page. I split it out into its own page.
https://trac.torproject.org/projects/tor/wiki/doc/DnsPluggableTransport
Feel free to add to the page by creating an account or with the anonymous credentials on the home page.
David Fifield