Skip to content
trevj edited this page Jan 9, 2017 · 22 revisions

Introduction

We'd like to run uProxy cloud servers on Node.js because it will be cheaper and simpler than running inside Firefox on a (headless) X server.

Status

freedom-for-node uses something called wrtc to provide core.rtcpeerconnection. wrtc is a thin layer (as are several other WebRTC-on-Node.js-type NPMs) over something called build-webrtc which makes it possible to compile WebRTC for Node.js.

This enabled us to provide a Simple SOCKS that ran on Node.js. Great, right? We were even able to make Zork run on Node.js, complete with obfuscation. However, there were two major problems:

  1. it was extremely slow: ~25% of Firefox's throughput
  2. it was affected much more by latency than either Chrome or Firefox - >66% slowdown when that latency rises to ~150ms

The latency issue was doubly puzzling because uProxy made changes to Chrome in 2015 to improve throughput in the presence of high latency between peers - and wrtc is built from the same source.

We had some theories on why performance was so bad under freedom-for-node (threadpools, perhaps https://github.com/uProxy/uproxy/issues/2612#issuecomment-244219541) but once some quick experiments indicated that Chrome-level performance could be reached by running directly against wrtc, we decided to take that route instead. So, we've been re-writing Zork, merging our changes into the https://github.com/uProxy/uproxy/tree/trevj-socks-refactor branch - see below for how to run it.

Open issues

  • wrtc is temperamental: it only supports a couple of architectures out of the box and some patching is required to make it run under Linux/Docker.
  • No support for obfuscation.

HOWTO

Build Zork-for-Node.js

cd to your uproxy clone and run:

git checkout trevj-socks-refactor
yarn run clean
yarn
yarn run grunt zork

Build wrtc

OSX users can skip this step: wrtc compiles cleanly there.

Build

Linux users, including those building for Docker, should follow this (strictly speaking, wrtc currently does install easily on a handful of distributions - but they are getting older and older). We'll need to check out two Github repos, make some patches, and compile WebRTC. The whole process takes at least ~15GB of disk space and ~30 minutes - if you intend to run on a system like a Raspberry Pi, you'll need to cross-compile.

First, checkout these two repos:

git clone https://github.com/markandrus/build-webrtc.git
git clone https://github.com/js-platform/node-webrtc.git

Next, apply some patches:

'include_pulse_audio=0',
'include_internal_video_render=0'
git fetch origin pull/287/head:fake_audio_device
git checkout fake_audio_device
git merge develop

Now, we're ready to build:

cd node-webrtc
export SKIP_DOWNLOAD=true
export BUILD_WEBRTC_DEPENDENCY=/work/build-webrtc/
npm install

To test:

node examples/ping-pong-test.js

Cleanup:

rm -fR node_modules/build-webrtc third_party

(more advice on custom builds at https://github.com/js-platform/node-webrtc/wiki/Building)

Building on and for Docker

Here are the commands and dependencies you'll need:

docker run --rm -ti -v $PWD:/work -w /work ubuntu:yakkety
apt-get update
apt-get install -y curl make git python binutils g++ alsa-base pulseaudio
curl -sL https://deb.nodesource.com/setup_6.x | bash -
apt-get install -y nodejs
npm install -g yarn
echo 'unsafe-perm = true' > /root/.npmrc

Building for Alpine

I couldn't get it to build on Alpine - the ninja step fails (same stumbling block as Raspberry Pi).

apk add python make git bash binutils g++ curl tar findutils ninja

But maybe we don't need to, just "cross-compile" for Alpine???

Patch

In your uProxy clone, delete node_modules/wrtc and copy the entire node-webrtc there, e.g. cp ~/node-webrtc ~/uproxy/node_modules/wrtc).

Run

Quick

Useful for quick and dirty tests:

node build/src/lib/zork/

Backwards Compatibility Tests

cd to your uProxy clone and:

./docker/testing/run-scripts/image_make.sh node stable
./docker/testing/run-scripts/run_pair.sh -p firefox-stable node-stable

Why the -p? Older Zorks assume servers support obfuscation which isn't true of Zork-on-Node.js - our branch has a quick 'n' dirty patch to workaround that.

Deploy a cloud server

If you haven't already done so, build a Docker image for Zork (see above). We'll need to push the image to Docker Hub. Tag the image so that we can push it to Docker Hub without replacing any existing images, e.g. docker tag uproxy/node-stable trevj/node2.

Now, SSH into your server and run:

git clone https://github.com/uProxy/uproxy.git
cd uproxy
git checkout trevj-socks-refactor
./docker/testing/run-scripts/run_cloud.sh -z trevj/node2