Real time over TOR

Setup details covering how to setup a private tor network, how to setup openvpn, and how to setup sip server and voip client(s).

Configuration files are available on github.

Setting up private TOR

A complete private TOR network consists of the following-
  • Tor Directory Server
  • Tor Relays
  • Tor Client
The setup is non-trivial when being done for the first time. Since there is already an elaborate tutorial for this setup by Fengy, I will not spend time on the details. However, here's a quick overview of what all needs to be done to setup a private Tor network.
  1. Install Tor - In our case, we will compile the source, instead of using some package manager.
  2. Generate keys - We need to generate (various) keys for all the components of the network (directory server, relays and clients).
  3. Create torrc files - We need to do this for all the components. The torrc will have some differences depending on what the function of that tor instance will be (i.e. ds, relay or client), but some structure would be shared.
  4. Add fingerprints - We need to add directory server details and fingerprints to all torrc's.
Use nyx (formerly arm) to verify that your private tor is working well. It also has a torctl interpreter for fine tuning circuits, etc.
Try to avoid running tor as root. For this, you have to change ownership of all folders required by tor from root to your current user (eg. /var/lib/tor). Warnings/errors when running tor without root will tell you exactly which folders need ownership change.

OpenVPN

Once we have tor set up, we need to install openvpn on the machine which contains the tor client, as well as on the machine intended to be the vpn server. First we run the vpn on the server (sudo /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid) and start listening on some port. We then write an openvpn configuration specifying the server address and listening port, as well as the socks proxy port opened by tor locally. Once we run the openvpn client, we have a tunnel from the client to the server via our private tor network.

If you are having trouble with bandwidth, try looking at top output to see if CPU usage is hitting 100%. VPN compression + cryptography, as well as tor cryptography are very resource intensive and usually a single core can't push more than 700-800mbps irrespective of available bandwidth.

SIP server and voip client

Finally, we need to setup a SIP server (in our case we use freeswitch, and put it on the same machine as the openvpn server) and configure a voip client to communicate with that SIP server. We are using pjsip for that. The freeswitch configuration needed to be changed a bit. Also, we need to use a script called record-samples.py on the client, and give it appropriate paramters. The parameters can be identified by looking at the docker commond invocation done by runner.go. Since the runner.go script print the invoked docker command to stdout, there is no need to read the source.

TODO: This configuration needs to be expaned. The SIP server should be made separate from the VPN server in the general case, and there should be a second client and full duplex voice calling.
Freeswitch changes
  • freeswitch/conf/directory/default - We need to create around 1000-2000 extensions here. A simple script (extensionGen.py) is available for this.
  • freeswitch/conf/dialplan/default - Here we need to configure playback options. See 01_Ajit.xml in github.
  • freeswitch/conf/vars.xml - X-PRE-PROCESS cmd="set" data="local_ip_v4=10.8.0.1"
  • Compiling pjsua python
    Here are the steps to compile pjsua. Notice that we need to edit pjsua_media.c to avoid an issue which limits number of simultaneous calls to 100.
                
    sudo apt-get install build-essential python-dev binutils make gcc libasound2-dev
    tar -xf pjproject-2.7.2.tar.bz2 && cd pjproject-2.7.2/
    export CFLAGS="$CFLAGS -fPIC"
    Edit pjsip/src/pjsua-lib/pjsua_media.c and increase RTP_RETRY to 10000
    ./configure && make dep && make
    cd pjsip-apps/src/python/
    sudo python setup.py install
                
                
    Due to the RTP_RETRY edit, we will be able to go beyond 100 connnections. Now, after some point, we get errors saying too many open files. To fix that, go to this page https://stackoverflow.com/questions/26415833/docker-ignores-limits-conf-trying-to-solve-too-many-open-files-error. Instead of the '-', add 2 lines in limits file replacing - with soft and hard respectively. Logout and log back in for ulimit changes. Instead of *, use root, since * wildcard doens't apply to root and we are running our script as root.