TBNG  — Install and Setup Guide

TorBOX Next Generation

Install and Setup Guide


This document describes the steps for installing and configuring the TorBOX Next Generation (hereinafter TBNG) script set, a simple and convenient tool for creating access points to the Internet using the TOR (The Onion Router) pseudo-anonymous network.

It is assumed that user:

It is also assumed, that OS is fully functional, there is no problems with drivers, including network ones and system can access the Internet.

TBNG does not provide “pre-made images” or “working out-of-the box distribution” of any kind and no one will solve problems with drivers other than the user. It is a tool that enhances privacy and yes, it takes some effort to properly configure it.

System requirements

An excellent option is to put TBNG on a freshly installed system, where there are only standard packages.

TBNG is tested on the following equipment:

The amount of memory for comfortable work is 512 MB + Swap. A single-core processor from 600..800 MHz is also sufficient for operation.

TBNG is just a set of scripts. The main memory-hungry parts are web-interface and of course I2P, which uses Java.

Terms and assumptions

Let’s introduce some terms, just to be clear

We will call “outer” network (Internet) — WAN.

The network that TBNG will create for client access will be called LAN.

Let’s assume that the device (computer, single board computer) is connected to a router, and has access to the Internet. Let the router have the address, and the target device for TBNG received the WAN address 192.168.1.x. It can be either a wired interface or wireless, the main thing is to get access to the Internet.

LAN interface on TBNG has static address —

Also assume that the Linux user is called johndoe, so the home directory will be called /home/johndoe.

We will configure TBNG with two wireless network interfaces to illustrate the configuration of the access point on TBNG. The following figure shows an example of work:

TBNG example configuration

Getting TBNG project files

Files must be cloned from GIT repository.

johndoe@linuxbox:~$ git clone https://github.com/znoxx/tbng

After executing the command, a directory tbng will appear in the home directory.

johndoe@linuxbox:~$ ls -la tbng
drwxr-xr-x 10 johndoe johndoe 4096 Jul 31 13:51 .
drwxr-xr-x 21 johndoe johndoe 4096 Aug 10 13:19 ..
-rw-r--r--  1 johndoe johndoe 1876 Jul 14 20:24 app.js
drwxr-xr-x  2 johndoe johndoe 4096 Jul 25 12:01 bin
-rw-r--r--  1 johndoe johndoe  285 Jul 31 13:51 check-version.js
drwxr-xr-x  3 johndoe johndoe 4096 Aug  4 14:05 config
drwxr-xr-x  4 johndoe johndoe 4096 Aug  4 14:05 engine
-rw-r--r--  1 johndoe johndoe  570 Jul 31 13:51 package.json
drwxr-xr-x  5 johndoe johndoe 4096 Jul 14 20:24 public
-rw-r--r--  1 johndoe johndoe  198 Jul 14 20:24 README.md
drwxr-xr-x  3 johndoe johndoe 4096 Aug  4 14:05 routes
drwxr-xr-x  4 johndoe johndoe 4096 Aug  4 14:05 setup
drwxr-xr-x  2 johndoe johndoe 4096 Aug  4 14:05 views

Installation of required packages

Before configuration, installation of several packages is require. Also one will need Java for I2P and (and this is very importan) — node.js и npm to get web-interface functionality.

Node.js version — not earlier than 4.2.1.

Tested Java version — 8.

If system has alredy tor и privoxy installed — it is recommended to purge them with configuration files and re-install with default “factory” settings.

For Debian/Ubuntu users, the installation of packages is automated, for users of other distributions — the packages need to be installed via system package manager.

Automatic install for Debian/Ubuntu

The automatic package installation command is executed with superuser privileges:

johndoe@linuxbox:~$ sudo run-parts tbng/setup/apt

Auto-install scripts run for a considerable amount of time. The process will remove tor and privoxy, and their configuration will be saved to a backup. There will also be a couple of additional repositories for node.js.

OpenJDK and Debian Buster

Debian Buster lacks OpenJDK 8 package.

If your are getting OpenJDK install error , manually update version number in tbng/setup/apt/09-install.

Additional steps for Raspbian (Debian Stretch) on Raspberry PI 1

First of all, it’s worth mentioning that for RPI 1 the work was checked only in the new Debian Stretch. The version of the headless system finally became available, and also it’s just the newest distribution, which should be used.

Raspberry PI 1 requires additional steps even with automatic installation of required packages.

The node.js installation script reports that there is no node.js for the armv6l architecture, and a version from Stretch/Raspbian repository will be installed. It must be replaced with a newer version:

johndoe@linuxbox:~$ sudo apt-get purge nodejs
johndoe@linuxbox:~$ wget http://node-arm.herokuapp.com/node_latest_armhf.deb
johndoe@linuxbox:~$ dpkg -i ./node_latest_armhf.deb
johndoe@linuxbox:~$ sudo apt-get install npm
johndoe@linuxbox:~$ ln -s /usr/local/bin/node /usr/bin/nodejs

Generally those steps are sufficient to continue.

List of packages for manual install in other distributions

Packages are named as in Debian / Ubuntu. Perhaps some names do not match, you may also need to install the python3 modules via pip. However, this list should be sufficient to find all required packages.

curl, sudo, network-manager, iptables, nodejs, python3, tor, tor-geoipdb, obfsproxy, obfs4proxy, privoxy, haveged, shellinabox, links, python3-pexpect, python3-requests, python3-lxml, python3-netiface, dnsutils, sed.

As it mentioned before, Java and npm must be installed also.

In general, there is a set of scripts in the setup/apt directory that installs packages, so that the user of another distribution will easily identify the actions that need to be performed on his system based on this data.

In addition to installing packages, there is one more important action that you should not forget to do when using non-Debian/Ubuntu — set SUID bit on nmcli.

Can be done like this:

NMCLILOCATION=$(which nmcli)
chmod u+s,a-w $NMCLILOCATION

This is required for correct web-interface operation and some other actions.

Network interfaces operation check-list

Before configuring TBNG, you need to make sure that the network interfaces “involved” in the work are configured correctly. As already mentioned, we have two zones - LAN and WAN.

LAN is used for TBNG clients, WAN — “outer world”. For consitency and according to figure abouve wlan0 is LAN, wlan1 — WAN.

In this case:

If WAN interface is wired, one must take care to configure it. It can be done via Network Manager, or via /etc/network/interfaces.

Special note on Ubuntu 18.04 (Bionic Beaver) and other distros, where systemd-resolved is used

Bionic Beaver introduced an innovation in the form of netplan utility, which allows you to configure network interfaces much easier. Unfortunately, both for maintaining compatibility with Debian and previous Ubuntu, and because of the peculiarities of netplan, the network is configured via the ifupdown mechanism.

So, if you use Bionic Beaver, you need to use the good old /etc/network/interfaces. Here is an example of its content for wlan0, which, as stated above, we use as LAN:

auto wlan0
iface wlan0 inet static

Also make sure, that netplan completely relies on network manager. Below is a config from Armbian, and it works.

$ cat /etc/netplan/armbian-default.yaml 
  version: 2
  renderer: NetworkManager

The next step is to disable the Network Manager from managing our adapters, for which a static address is set. Here is an example of running NetworkManager.conf:





Important sections — ifupdown и keyfile. They are both responsible for correct management of interfaces from /etc/network/interfaces via ifupdown.

Also systemd-resolved was introduced in Bionic Beaver along with netplan. It also must be disable to allow dnsmasq operation. Done in this way:

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

After this you can continue installation in Bionic Beaver.

Setting up hostapd and dnsmasq


The dnsmasq package performs many useful functions, but in our case it is needed for two important purposes:

dnsmasq can be instaled and configured manually , but TBNG do have helper setup script for it.

Script must be run with superuser rights (root). Let’s figure out how, using an example:

johndoe@linuxbox:~$ sudo tbng/setup/configure_dnsmasq.py -i wlan0 -s apt -b -e -m

Here we claim, that dnsmasq will work on interface wlan0 (-i wlan0), we will install it from apt-repository (-s apt), addresses will be assigned from to (options -b, -e) and subnet mask will be (-m).

There is also possible option “-s yum” — in this case dnsmasq installed via yum. Or one can use option “-s none”. In this case install step will be skipped and only configuration wiil be applied.

If command execution succeeds:

johndoe@linuxbox:~$ sudo systemctl restart dnsmasq

Setup is completed successfully. If LAN interface is wired, one can connect client to TBNG immediately and check, that address is assigned. If not — one must configure wireless access point.

To check DNSMasq is really used, run a command below. (Maybe you will need to install nslookup package):

nslookup github.com

Output should contain information about local DNS-server. If it is, then you are done. here is an example:

johndoe@linuxbox:~$ nslookup github.com

Non-authoritative answer:
Name:   github.com

If some other DNS-server is lister (not a, then you need additional config steps for your system. Refer to OS documenation.


If LAN interface is wireless, then in most cases one will need a wireless access point. Almost all modern distributions contain this package and there are lots of instructions on setting up on the Internet.

However, TBNG contains a helper script to configure the access point.

The user needs to configure the hostapd for the LAN zone (in our case wlan0 interface). This can be done via standart hostapd or with helper script.

Let’s check an example:

johndoe@linuxbox:~$ sudo tbng/setup/configure_hostapd.py -a armhf -i wlan0 -n my_access_point -p mysuperpassword -d nl80211

Options, used in this command:

In general, using a script for a beginner is the preferred way — all settings are done automatically, the binary file is static, all popular architectures are supported.

After installation, you can check the operation of the access point with a command (if one used a script):

johndoe@linuxbox:~$ sudo systemctl restart hostapd-tbng

If one used standard hostapd:

johndoe@linuxbox:~$ sudo systemctl restart hostapd

If the access point is visible, the installation was successful. Of course it happens that the network is visible, but there is no connection, but this is already a question to the operation of the equipment.

When using the script, the binary file can be found in the folder tbng/bin, and the configuration in tbng/config. In case of problems, you can run the binary from the command line and see what happens:

johndoe@linuxbox:~$ sudo tbng/bin/hostapd-tbng tbng/config/hostapd-tbng.conf

Configuration files preparation

One must prepare configuration files. TBNG is supplied only with sample files, from which you need to create real configuration files. This is done by simply copying from configfile.json.example files in configfile.json.

johndoe@linuxbox:~$ cp tbng/config/tbng.json.example tbng/config/tbng.json
johndoe@linuxbox:~$ cp tbng/config/user.json.example tbng/config/user.json
johndoe@linuxbox:~$ cp tbng/config/torcountry.json.example tbng/config/torcountry.json

Next, you need to edit the files, at least tbng.json, because it contains the key information necessary to work.

Configuration files format

The format used for configuration files is JSON (Javascript Object Notation). They can be edited in a regular text editor. The most important thing is to strictly follow the syntax of JSON. Unfortunately, the JSON format does not provide comments.


The most important configuration file. At least it must be aligned with network interface configuration on device with TBNG. Let’s take an example:

  "cputemp": "default",
  "wan_interface": [
     "name": "wlan1",
      "wireless": true,
      "macspoof": {
        "method": "ifconfig"
  "lan_interface": [
      "name": "wlan0"
  "allowed_ports_tcp" : [22,3000,7657,9050,8118,4200],
  "allowed_ports_udp" : [53],
  "lock_firewall": false

Below mandatory fields are listed.


The field shows which plug-in is used to read the temperature. At the moment, the value “default” is used, you can change it to the desired one (see the engine/plugins folder).


An array of network interfaces for the WAN zone. If more than one interface is specified, you can switch between interfaces.

The “wireless” attribute declares the interface as wireless. There can be only one wireless interface in the WAN list — this is due to the peculiarity of the web-interface. In the future, this restriction may be lifted.

The “macspoof” field describes the method by which the mac-address will be replaced, in other words here one sets plugin for “Mac spoof” operation. If the interface does not support such functionality it is better to completely remove it.


An array of network interfaces for the LAN zone. The main requirement is that the array should not intersect wan_interfaces. That is, you can not use wlan0 in both WAN and LAN simultaneously. The type of interface (wireless = true) can be omitted, it is not used.

Section must not be empty, since interface names are used for with IP Masquerading (NAT).


Arrays of ports opened in the firewall for the LAN zone. For example, the user has put some new service on the device with TBNG, and wants to use it on the local network. Then the port used by this service needs to be added to the list (depending on the type of tcp or udp the corresponding array should be added).

Of course, the ports can be “reduced”, although ports 22 and 3000 are always opened - specifically to ensure that the user can not lose access to the ssh and web-interface. If this should be excluded, we also edit the “engine” tbng/engine/tbng.py. But already at your own peril and risk (like everything else, however).


A sign that the firewall is closed. When set to true, the firewall blocks connections from the WAN. Set it only when everything is checked and working.


Arrays of ports opened in the firewall for the WAN zone. Almost the same as the previous similar option for LAN. Ports are available even if lock_firewall is set to true. In the default configuration settings is not used (WAN is “all closed”), but if TBNG is installed on a leased server (VPS), the configuration should be described for opening VPN, SSH, and other services.


Contains a name and password for accessing the web-interface. The default is webui/webui. Can be replaced with the desired values.


Contains a list of countries for TOR. Required for display in the web interface. If desired, you can slightly reduce it, say, leaving only those countries that are planned to be excluded when working through TOR.


This file appears only after the first start TBNG and is used to store settings and restore them. It is not intended for self-editing, but you can delete it if “something went wrong”, and reboot the system, or execute the command:

johndoe@linuxbox:~$ sudo tbng/engine/tbng.py mode restore

This will bring the system to its original state.

Primary TBNG setup

So, the settings are formed, the network interfaces are checked — the time to apply the final configuration and use. To start the configuration, do the following:

johndoe@linuxbox:~$ sudo tbng/setup/configure_componetns.py -u johndoe

This command does the follwing:

After successful run the system will be ready for use, it is recommended to conduct a power cycle (ie turn off and on).

If, for some reason, the tor and privoxy configuration files are somewhere else, you will need to specify them in the command line options — use the “–help” option).

After successful installation, three new services will appear in the system:

Congratulations, the system is configured and working !

Using TBNG with docker Docker and LXC

TBNG can be used together and along with the container systems - Docker and LXC. Packaging TBNG in Docker is not feasible, since the system consists of a set of components, and best practices for Docker imply the separation of the solution into components. However, TBNG can ensure the functioning of containers through TOR / Privoxy.

For LXC, there are no such restrictions, and TBNG fully works inside a separate LXC container. The case will be considered below.

Interaction with Docker

The use of TBNG in conjunction with the Docker is possible in two, unfortunately, mutually exclusive modes. This is due to the conflict / incompatibility of iptables rules. Perhaps, it will be solved in future versions.

For the first mode, no additional settings are required. Moreover, if the application in the container is capable to work through socks5 or http proxy, those settings can be utilized. As a server, you need to use LAN ip, as port use 9050 for socks5 or 8118 for http proxy.

For the second mode of interaction with Docker, you need to make several additional steps.

The docker0 interface should already be in the system at the time of setting up and then starting tbng. That is, it makes sense to install the Docker before installing TBNG.

The tbng service for systemd (see /lib/systemd/system/tbng.service) needs to be modified with a dependency on the Docker daemon. On a Debian / Ubuntu line like:


must be changed to:

After=network.target docker.service

It is also recomended to update /etc/docker/daemon.json with next settings:

    "dns": ["ip.of.your.lan.interface","ip.of.your.router",""]

First IP — the one from your LAN interfaces (one of those from tbng.conf LAN section). Next one is your router IP, and finally — Google dns.

The last step is to add the docker0 interface to the lan_interface section. After these manipulations, each Docker container will be able to use the TBNG functionality as if it were devices on a local network serviced by TBNG.

To test the functionality, you can use Docker images znoxx/tbng_ip_checker_x86_64, znoxx/tbng_ip_checker_arm64, znoxx/tbng_ip_checker_armhf by simply launching an image that matches the architecture with the docker run command. Alternatively, you can build the image yourself by running the docker build . command in the tbng/tests/tbng_checker directory.

Installing TBNG into LXC container

TBNG can be installed in the LXC 2.x container. During the testing it was possible to get a fully functioning version of TBNG, installed in the container Ubuntu Xenial with the wireless interface attached to the container exclusively. That is, the WAN interface was eth0 of the container, LAN was wlan0 (the second network interface of the container), the access point worked inside the container and successfully distributed addresses via DHCP.

Brief install scenario:

Attaching physican network interface to container

lxc-wait -n tbng -s RUNNING
lxc-device -n tbng add wlan0

This script should be run in the background. After that, you can run the container: lxc-start -n tbng. We wait, that the container “tbng” started, we attach the device. It should be noted that this makes it difficult to autorun the container at system startup, but you can refer to the LXC documentation and enter the device’s forwarding directly into the container configuration.

Start dnsmasq

Since in our case wlan0 is connected late, there is a possibility that dnsmasq will not start normally, without finding wlan0. There are two ways to solve this problem:

The first way is much more elegant, but there is a possibility of changing dnsmasq.service when updating the system with the loss of changes.

Finally, installation of TBNG inside the LXC container has no differences with installing on a regular computer.


TBNG is written in Python, and almost all actions are formalized. That is, calling iptables, starting and stopping daemons, working with Network Manager will be the same almost everywhere, but here are the procedures for reading the processor’s temperature, or spoofing mac-addresses will differ not only from core to kernel, but even from system to system. In connection with this, a plug-in mechanism was introduced — plug-ins that implement a small and optional functionality

Plugins are located in the folder tbng/engine/plugins and are named according to the principle family_name.py, where family is a family (for example cputemp), and name is the name that characterizes the plugin. For example, cputemp_default.py reads the CPU temperature in the “normal” way from the cpu0 processor sensor.

At the time of writing, there are only two families — cputemp and macspoof. The first, as it was said, realizes the mechanism of reading the temperature of the processor, the second is the substitution of the mac-address of the network card.

The “example” family is just test plug-ins for development.

The tbng.json configuration file specifies only the action — “cputemp: default”, “macspoof: ifconfig”.

Plugins for reading CPU temperature information

The simplest type of plugins. Read the temperature data, form a string, and transmit it to the standard output.

The file is named cputemp_action.py. Check functionality is simple:

johndoe@linuxbox:~$ sudo tbng/engine/plugin_tester.py cputemp default

If the plug-in brought out the temperature, the test was successful. But on the Raspberry Pi 1 process of reading the temperature is different and you need to use the plugin cputemip_rpi1.py, that is:

johndoe@linuxbox:~$ sudo tbng/engine/plugin_tester.py cputemp rpi1

Plugins for mac spoof

MAC spoof allows you to replace the interface address of the WAN zone. Most likely the user knows the purpose for this action.

The main problem is that mac spoofing works differently on different kernels, kernel modules, and on different hardware.

For example, if the Ralink 2800 adapters perfectly change the MAC address through the ifconfig command (although only in Debian Jessie and Debian Stretch, but not in Ubuntu - there “hinders” Network Manager of a certain version), then to change the MAC on Realtek adapters, you need to unload the current kernel module , execute modprobe with the parameter (new mac). And it turns out that if you have 2 identical Realtek network adapters, the action will be performed for both (since they share one kernel module). And this will definitely put the system into an inoperative state. Experimental or buggy modules for example has even more obstacles.

Unlike the “temperature” plug-ins for macspoof, you need to pass parameters, at least the name of the interface that you need to “spoof”.

Here are examples of using plugins in the tbng.conf configuration file and in the plugin_tester.py utility.


Performs the substitution of MAC addresses through the command ifconfig — the most simple option. Does not work in Ubuntu (however, it works in Debian Jessie and Stretch).

Configuration file record

Format is almost straightforward:

     "name": "wlan1",
      "wireless": true,
      "macspoof": {
        "method": "ifconfig"

Enabling spoof on wlan1 interface.

Call via plugin_tester

On the command line, you need to pass a JSON string with the interface name:

johndoe@linuxbox:~$ sudo tbng/engine/plugin_tester.py macspoof ifconfig '{"name":"wlan1"}'


Performs a substitution of the mac address by unloading the module and reloading it again with the parameter. Can not be used if there is more than one interface of the same type (for example, both wlan0 and wlan1 use the same 8192cu module). Also will not work on systems where the interface name contains a mac-address.

Configuration file record

Format is slightly more complicated:

     "name": "wlan1",
      "wireless": true,
      "macspoof": {
        "method": "modrealtek",
        "parameters": {
         "module_name": "8192cu"

Enable spoof on wlan1 interface and point to kernel module name which must be reloaded.

Call via plugin_tester

On the command line, you need to pass a JSON string with the interface name and kernel module name for reloading:

johndoe@linuxbox:~$ sudo tbng/engine/plugin_tester.py macspoof modrealtek '{"name":"wlan1","module_name":"8192cu"}'

Creating your own plugin

To write your own plug-ins you need Python 3.x.

The plugin is started by calling the plugin_main function. To get started, several plug-ins are delivered including elementary families “example”, for testing you can use the utility tbng/engine/plugin_tester.py. The use is fairly strtaightforward and will not raise questions even for a beginner in Python, especially since all source code is available.