obfs4proxy is a pluggable transport for Tor, which can allow users to defeat certain types of network censorship. (Read some great information about pluggable transports — and how they work — here and here.)
This work is supported in part by The Guardian Project.
- it can be built as a framework, with an externally-visible
- some of the environment variables that obfs4proxy (and other pluggable transports) expect are hard-coded in, such that we "fake" managed mode, per this. the
$TMPDIRenvironment variable, which on iOS contains the path to the app’s designated (sandboxed) temporary directory.
- the socks5 ports for the Tor<->obfs4proxy connections are hard-coded so the iOS side knows what to connect to. (TODO: this will be removed once we have a better way to communicate this out from obfs4proxy into the iOS main thread.)
The framework contains a header that exposes a
GoIobfs4proxyMain(); function (the original
main() from obfs4proxy). Note that this function must be called inside an NSThread subclass, otherwise your iOS app will be blocked on that function call. You can use
ObfsThread.m from this repo to do this for you.
In the future, iObfs will wrap the build script,
ObfsThread utilities in a framework using Carthage to improve reusability -- see branch. A go compilation issue prevents this from working at the moment.
Please see the GitHub issues for known issues and caveats.
Using obfs4proxy in your app
(Note: this framework and these instructions are very much in development, so your mileage may vary. Some comfortability with Tor configuration is assumed.)
Given that you already have an iOS app with integrated Tor. On your machine, you'll also need a recent version of Go to build obfs4proxy. (1.5 should work, but this work has only been tested in Go 1.6.)
bash build.sh and wait a little while.
ObfsThread.m into your existing Tor-powered iOS app.
Set the following lines in your app’s
ClientTransportPlugin obfs4 socks5 127.0.0.1:47351 ClientTransportPlugin meek_lite socks5 127.0.0.1:47352 ClientTransportPlugin obfs2 socks5 127.0.0.1:47353 ClientTransportPlugin obfs3 socks5 127.0.0.1:47354 ClientTransportPlugin scramblesuit socks5 127.0.0.1:47355
Instantiate Tor normally within your app, then run an
ObfsThread instance in your app (you might want to check first that the user has
Bridge lines that require the pluggable transport). Something like:
ObfsWrapper *obfsproxy = [[ObfsWrapper alloc] init]; [obfsproxy start];
Then, if a user has the appropriate
Bridge lines using one of those tranpsports (and given that you've set
UseBridges 1 appropriately), your app’s Tor should successfully use obfuscated bridges.
You can see a short version of this in the
example/ directory. The README will guide you through a couple of the commits.