I want to build it from scratch on a Raspberry Pi with Raspberry Pi OS Lite!

Whether you like to implement TorBox to an existing system, to another hardware, respectively another operating system, or you don’t trust an image file, which you didn’t bundle of your own, this detailed manual helps you to build a TorBox from scratch.

This manual is written for Raspberry Pi OS “Buster” Lite (based on Debian 10 “Buster”) on a Raspberry Pi 3 (Model B / Model B+) or Raspberry Pi 4 Model B.

Before you create all configuration files by yourself: some of the below-mentioned configuration files are stored in the “TorBox Menu” file or on our GitHub page in the “etc” folder.

1. Prepare your system
  1. Download the latest version of the Raspberry Pi OS Lite (about 435 MB)
  2. Transfer the downloaded Raspian Lite image on an SD Card; for example, with Etcher. TorBox needs at least a 4 GB SD Card, but at least 8 GB are recommended.
  3. Log into your newly set up system and configure it with “sudo raspi-config”.
    Important
    You must set the “WLAN country” (in raspi-config menu entry 4 – i4), or TorBox doesn’t
    work because WiFi is blocked!!
    – You need to have a stable internet connection.

An alternative way to unblock WiFi on Rapberry Pi OS whitout using raspi-config:

sudo iw reg set US
sudo sed -i "s/^REGDOMAIN=.*/REGDOMAIN=US/" /etc/default/crda
sudo rfkill unblock wlan
2. Update your system and install all necessary packages

To build a TorBox from scratch, some packages have to be installed first. To be sure to have the latest version of the base system, the package list, and the firmware, you should use the following commands:

sudo apt-get -y update
sudo apt-get -y dist-upgrade
sudo apt-get -y clean
sudo apt-get -y autoclean
sudo apt-get -y autoremove

Depending on the updated packages (firmware, kernel, driver etc.) a reboot is recommended.

Following additional packages are necessary and have to be installed:

  • hostapd -> provides a wireless access point (AP).
  • isc-dhcp-server -> act as our DHCP server.
  • tor, obfs4proxy -> gives access to the Tor network (tor will be installed later, see further below).
  • usbmuxd -> a socket daemon to multiplex connections from and to iOS devices (support for tethering with iOS devices).
  • wicd-curses -> an easy to use wireless network connection manager (wicd stands for “Wireless Interface Connection Daemon”).
  • dnsmasq -> DNS forwarder (necessary to deal with captive portals).
  • dnsutils, tcpdump, iftop, vnstat, links2 -> analytical and statistical network tools.
  • debian-goodies, apt-transport-https -> other necessary tools.
  • dirmngr -> GNU privacy guard – network certificate management service.
  • python3-setuptools, python3-pip -> necessary tools for Python 3.
  • python3-pil, imagemagick, tesseract-ocr -> necessary libraries and programs for bridges_get.py.
  • ntpdate -> necessary to set the correct system time.
  • screen -> a terminal multiplexer allowing a user to access multiple separate login sessions inside a single terminal window, or detach and reattach sessions from a terminal.
  • nyx -> a command-line monitor for Tor.
  • git -> distributed revision control system (needed by LCD-show).
  • openvpn -> software that implements virtual private network.

Install all necessary packages with the following command:

sudo apt-get -y install hostapd isc-dhcp-server obfs4proxy usbmuxd wicd-curses \
dnsmasq dnsutils tcpdump iftop vnstat links2 debian-goodies apt-transport-https \
dirmngr python3-setuptools python3-pip python3-pil imagemagick tesseract-ocr \
ntpdate screen nyx git openvpn

# Additional installations for Python
sudo pip3 install pytesseract
sudo pip3 install mechanize

We don’t want to start dnsmasq automatically after booting the system:

sudo systemctl disable dnsmasq
3. Disable Bluetooth

Because of security considerations, we recommend disabling the Bluetooth functionality of your Raspberry Pi completely.

# Change your /boot/config.txt:
sudo nano /boot/config.txt

# Add to the end of /boot/config.txt:
dtoverlay=disable-bt

# Run following command to disable the related services:
sudo systemctl disable hciuart.service 
sudo systemctl disable bluealsa.service 
sudo systemctl disable bluetooth.service

# Remove the Bluetooth stack to make Bluetooth unavailable even if external Bluetooth adapter is plugged in:
sudo apt-get -y purge bluez 
sudo apt-get -y autoremove

You have to reboot your Raspberry Pi to apply the changes.

4. Setting up a DHCP server
# Set up your hostname (for example "TorBox" instead of "raspberrypi":
sudo nano /etc/hostname
sudo nano /etc/hosts

# Adjust the configuration file of the DHCP server:
sudo nano /etc/dhcp/dhcpd.conf

# Replace /etc/dhcp/dhcpd.conf with the following content:
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
authoritative;

subnet 192.168.42.0 netmask 255.255.255.0 {
range 192.168.42.10 192.168.42.50;
option broadcast-address 192.168.42.255;
option routers 192.168.42.1;
option domain-name "local";
option domain-name-servers 192.168.42.1;
}

subnet 192.168.43.0 netmask 255.255.255.0 {
range 192.168.43.10 192.168.43.50;
option broadcast-address 192.168.43.255;
option routers 192.168.43.1;
option domain-name "local";
option domain-name-servers 192.168.43.1;
}

# Adjust the configuration file of the DHCP server (isc-dhcp-server):
sudo nano /etc/default/isc-dhcp-server

# Add all the available interfaces to the following line:
INTERFACEv4="wlan0 wlan1 eth0 eth1"

The classless static route option (RFC3442) gives us some headaches with certain AP under certain conditions (see also here). Therefore we remove this option from the configuration:

# Remove in /etc/dhcp/dhclient.conf the classless static route option
sudo nano /etc/dhcp/dhclient.conf

# Old entries:
option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

request subnet-mask, broadcast-address, time-offset, routers, domain-name,
domain-name-servers, domain-search, host-name, dhcp6.name-servers,
dhcp6.domain-search, dhcp6.fqdn, dhcp6.sntp-servers, netbios-name-servers,
netbios-scope, interface-mtu, rfc3442-classless-static-routes, ntp-servers; 

# New entries:
#option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

request subnet-mask, broadcast-address, time-offset, routers, domain-name,
domain-name-servers, domain-search, host-name, dhcp6.name-servers,
dhcp6.domain-search, dhcp6.fqdn, dhcp6.sntp-servers, netbios-name-servers,
netbios-scope, interface-mtu, ntp-servers;
5. Setting up network interfaces

Currently, TorBox supports the following connections:

INTERNET     CLIENT           Remarks
--------------------------------------------------------------------------------------------
ETH0         WLAN0(+ETH1)     Cable-internet (onboard ethernet adapter) - STANDARD
ETH1         WLAN0(+ETH0)     USB ethernet adapter or Tethering (iOS)
WLAN1        WLAN0(+ETH0)     Wireless-internet (USB wireless adapter, usually 2.4 GHz only)
WLAN0        WLAN1(+ETH0)     Wireless-internet (onboard chip, with >RPi3B+: 2.4/5 GHz)
USB0	     WLAN0(+ETH0)     USB dongle or Tethering (Android) (ppp0; usb0)
PPP0         WLAN0(+ETH0)     Cellular-internet
TUN0         WLAN0(+ETH0)     Over a VPN connection

 In the beginning, only the standard /etc/network/interface — listed below — is necessary. Depending on your choice in the TorBox menu, this file is altered by TorBox automatically.

# Edit /etc/network/interfcae:
sudo nano /etc/network/interface

# Replace /etc/network/interface with the following content:
source-directory /etc/network/interfaces.d

auto lo
auto usb0

iface lo inet loopback
iface eth0 inet dhcp
iface wlan1 inet dhcp
iface usb0 inet dhcp
allow-hotplug wlan0 wlan1 eth0 eth1 usb0

iface wlan0 inet static
  address 192.168.42.1
  netmask 255.255.255.0

iface eth1 inet static
  address 192.168.43.1
  netmask 255.255.255.0

wireless-power off
6. Configuring the TorBox AP
# Edit /etc/hostapd/hostapd.conf
sudo nano /etc/hostapd/hostapd.conf

# Replace /etc/hostapd/hostapd.conf with the following content:
interface=wlan0
driver=nl80211
ssid=TorBox032
country_code=US
hw_mode=g
channel=6
ieee80211n=1
ieee80211ac=1
wmm_enabled=1
#ht_capab=[HT40-][HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]
#vht_oper_chwidth=1
#vht_oper_centr_freq_seg0_idx=42
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=CHANGE-IT
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

Important

  1. Only letters (upper and lower case) and numbers are allowed in the passphrase. The length must be between 8 and 63 characters.
  2. Don’t remove or change the “#-lines” and the “country_code=US” value! Otherwise, the 2.4 GHz 40 MHz and the 5 GHz 40 and 80 MHz settings will most likely not work and probably crash hostapd! In use, TorBox changes this file along to the selection in the configuration sub-menu. However, if you delete values (even the ones with #), TorBox doesn’t re-add them again!
# Edit /etc/default/hostapd
sudo nano /etc/default/hostapd

# Old entry:
#DAEMON_CONF=""

# New entry:
DAEMON_CONF="/etc/hostapd/hostapd.conf"

This ensures the automatic start of the services when TorBox is started and also starts them immediately.

sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapd
sudo systemctl unmask isc-dhcp-server
sudo systemctl enable isc-dhcp-server
sudo systemctl start isc-dhcp-server
sudo systemctl disable dhcpcd
sudo systemctl daemon-reload
7. Configuring Network Address Translation (NAT)
# Edit /etc/sysctl.conf:
sudo nano /etc/sysctl.conf

# Old entry:
#net.ipv4.ip_forward=1

# New entry:
net.ipv4.ip_forward=1

# With the following command, we have to enable IP forwarding (necessary to overcom caprive portals):
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
8. Installing and configuring Tor

First step: Installing the latest stable version of Tor
By default, Raspberry Pi OS offers an old stable package of Tor (version 0.3.5.x). However, we should install the latest version of Tor (currently version 0.4.2.x) to benefit from the bug fixes and improvements.

# We have to edit /etc/apt/sources.list to add the Tor repository:
sudo nano /etc/apt/sources.list

# We have to add the following repositories:
deb https://deb.torproject.org/torproject.org buster main
deb-src https://deb.torproject.org/torproject.org buster main

# Then execute the following commands:
cd
sudo curl https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install tor deb.torproject.org-keyring

Second step: Configuring Tor

# Edit /etc/tor/torrc
sudo nano /etc/tor/torrc

# Replace /etc/tor/torrc with the following content:
## This is the configuration file of Tor
## DON'T CHANGE THE FOLLOWING 13 LINES!
######################################################
## Configuration for TorBox

Log notice file /var/log/tor/notices.log
VirtualAddrNetworkIPv4 10.192.0.0/10
AutomapHostsSuffixes .onion,.exit
AutomapHostsOnResolve 1
TransPort 192.168.42.1:9040
#TransPort 192.168.43.1:9040
DNSPort 192.168.42.1:9053
#DNSPort 192.168.43.1:9053
SocksPort 192.168.42.1:9050
#SocksPort 192.168.43.1:9050
DisableDebuggerAttachment 0
ControlPort 9051
HashedControlPassword 16:E68F16640ED8C0F7601F5AA3D229D8DFD8715623CB055577F9434F7FB7

## THE CONFIGURATION OF THE BRIDGE RELAY STARTS HERE!
######################################################
## This set up an obfs4 bridge relay.
#BridgeRelay 1
#ORPort 4235
#ExtORPort auto
#ServerTransportPlugin obfs4 exec /usr/bin/obfs4proxy
#ServerTransportListenAddr obfs4 0.0.0.0:443
#ContactInfo <[email protected]>
#Nickname TorBox032

## TO OVERCOME A FIREWALL, START HERE!
## HOWEVER, USE IT ONLY, IF REALLY NECESSARY!
######################################################
## This allows you to run Tor as a client behind a firewall with
## restrictive policies, but doesn't allow you to run as a server behind such
## a firewall.
## ReachableAddresses IP[/MASK][:PORT]…
## A comma-separated list of IP addresses and ports that your firewall allows
## you to connect to. The format is as for the addresses in ExitPolicy, except
## that "accept" is understood unless "reject" is explicitly provided. For
## example, 'ReachableAddresses 99.0.0.0/8, reject 18.0.0.0/8:80, accept *:80'
## means that your firewall allows connections to everything inside net 99,
## rejects port 80 connections to net 18, and accepts connections to port 80
## otherwise.
#ReachableAddresses *:80, *:443

## TO OVERCOME CENSORSHIP, START HERE!
######################################################
## If you like to use bridges to overcome censorship, EDIT THE LINES BELOW!
## To use bridges, uncomment the three lines below...
#UseBridges 1
#UpdateBridgesFromAuthority 1
#ClientTransportPlugin obfs4 exec /usr/bin/obfs4proxy

## ...and add your bridges below (the bridges below are examples which may or
## may not work. Uncomment to use them). Please give us feedback, if some of
## the bridges below doesn't work anymore: [email protected]
##
## You have two ways to get new bridge-addresses:
## 1. Get them here https://bridges.torproject.org/
##    (chose "Advanced Options", "obfs4" and press "Get Bridges)
## 2. Or send an email to [email protected], using an address
##    from Riseup, Gmail or Yahoo with "get transport obfs4" in the
##    body of the mail.

Important
Don’t remove or change the “#-lines”. TorBox changes this file automatically. If you delete values (even the ones with #), TorBox doesn’t re-add them again, and TorBox may not work correctly!

You should change the “HashedControlPassword” at the end of the installation with the help of the configuration sub-menu entry 9.

Third step: Configuring obfs4proxy

# Execute the following commands:
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/obfs4proxy
sudo sed -i "s/^NoNewPrivileges=yes/NoNewPrivileges=no/g" /lib/systemd/system/[email protected]
sudo sed -i "s/^NoNewPrivileges=yes/NoNewPrivileges=no/g" /lib/systemd/system/[email protected]

Fourth step: Activate Tor

# Execute the following commands:
sudo systemctl unmask tor
sudo systemctl enable tor
sudo systemctl start tor
sudo systemctl daemon-reload
9. Configuring the Wireless Interface Connection Daemon (wicd)

The Wireless Interface Connection Daemon (wicd) is an easy to use network connection manager. It provides a graphical text-interface to choose, configure, and connect to a wireless network. Usually, it is not necessary to run it manually. If needed, TorBox starts it for you.

# Edit /etc/wicd/manager-settings.conf
sudo nano /etc/wicd/manager-settings.conf

# Change following lines (yes, eth2 is right!):
wireless_interface = wlan1
wired_interface = eth2
dhcp_client = 1

# Edit /etc/wicd/wired-settings.conf
sudo nano /etc/wicd/manager-settings.conf

# Change following line
dhcphostname = TorBox032
10. Installing the TorBox Menu

The “TorBox Menu” is a user-friendly way to use and change the settings of your TorBox. The menu is automatically started, whenever a Terminal or an SSH-client access TorBox’s IP address (192.168.42.1). The menu works with shell scripts, which set the correct packet filtering and NAT rules as well as starts other supporting tools. All scripts are located under “~/torbox”. If necessary, the menu can be started there with “./menu”. Use the following commands to install the menu (or download the complete TorBox repository from our GitHub page):

# Execute the following commands:
cd ~
wget https://github.com/radio24/TorBox/archive/master.zip
unzip master.zip
rm -r torbox
mv TorBox-master torbox
rm -r master.zip

# Edit .profile:
sudo nano .profil

# Add the following lines to the end of ".profile":
cd torbox
sleep 2
bash menu

Optionally, in ~/torbox/etc/motd you can find a logo, which you can copy into your /etc/motd.

# Execute following commands:
cp ~/torbox/etc/motd /etc/motd

 Finally, you need to change /etc/rc.local to be sure, that TorBox will work properly after a restart:

# Edit /etc/rc.local:
sudo nano /etc/rc.local

# Replace /etc/rc.local with the following content:
#!/bin/sh -e
#
# rc.local
#
# Added by TorBox
rfkill unblock all

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

# Added by TorBox
if grep "iface wlan1 inet static" /etc/network/interfaces || grep "^interface=wlan1" /etc/hostapd/hostapd.conf ; then
  sudo ifdown wlan0
  sudo ifdown wlan1
  sudo sed -i "s/^auto wlan0/auto wlan1/" /etc/network/interfaces
  sudo sed -i "s/^iface wlan0 inet dhcp/iface wlan1 inet dhcp/" /etc/network/interfaces
  sudo sed -i "s/^iface wlan1 inet static/iface wlan0 inet static/" /etc/network/interfaces
  sudo sed -i "s/^interface=wlan1/interface=wlan0/" /etc/hostapd/hostapd.conf
  sudo ifup wlan0 &amp;>/dev/null &amp;
  sudo ifup wlan1 &amp;>/dev/null &amp;
  sudo systemctl restart hostapd
  sudo systemctl restart isc-dhcp-server
  sleep 5
fi

sudo /sbin/iptables-restore < /etc/iptables.ipv4.nat
sudo systemctl start dnsmasq
sleep 10
sudo /usr/sbin/ntpdate pool.ntp.org
sudo systemctl stop dnsmasq

exit 0

# Create or edit /etc/iptables.ipv4.nat:
sudo nano /etc/iptables.ipv4.nat

# Replace /etc/iptables.ipv4.nat with the following content:
*filter
:INPUT DROP [384:97594]
:FORWARD DROP [2:612]
:OUTPUT ACCEPT [32451:18744664]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m state --state INVALID -j DROP
-A INPUT ! -s 192.0.0.0/8 -i wlan0 -j LOG --log-prefix "SPOOFED PKT "
-A INPUT ! -s 192.0.0.0/8 -i eth1 -j LOG --log-prefix "SPOOFED PKT "
-A INPUT ! -s 192.0.0.0/8 -i wlan0 -j DROP
-A INPUT ! -s 192.0.0.0/8 -i eth1 -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -i wlan0 -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A FORWARD -m state --state INVALID -j DROP
-A FORWARD -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A FORWARD -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A OUTPUT -m conntrack --ctstate INVALID -j DROP
-A OUTPUT -m state --state INVALID -j DROP
-A OUTPUT ! -s 127.0.0.1/32 ! -d 127.0.0.1/32 ! -o lo -p tcp -m tcp --tcp-flags RST,ACK RST,ACK -j DROP
-A OUTPUT -o eth0 -p tcp -m tcp --dport 53 -j LOG --log-prefix "SSH SHELL DNS-REQUEST TCP" --log-tcp-options --log-ip-options
-A OUTPUT -o eth0 -p udp -m udp --dport 53 -j LOG --log-prefix "SSH SHELL DNS-REQUEST UDP" --log-ip-options
COMMIT
#
#
*nat
:PREROUTING ACCEPT [531:153102]
:INPUT ACCEPT [2303:137217]
:POSTROUTING ACCEPT [81:6206]
:OUTPUT ACCEPT [80:6038]
-A PREROUTING -d 192.168.42.1/32 -i wlan0 -p tcp -j REDIRECT
-A PREROUTING -d 192.168.43.1/32 -i eth1 -p tcp -j REDIRECT
-A PREROUTING -i wlan0 -p tcp -j REDIRECT --to-ports 9040
-A PREROUTING -i eth1 -p tcp -j REDIRECT --to-ports 9040
-A PREROUTING -i wlan0 -p udp -m udp --dport 53 -j REDIRECT --to-ports 9053
-A PREROUTING -i eth1 -p udp -m udp --dport 53 -j REDIRECT --to-ports 9053
-A PREROUTING -i wlan0 -p udp -j REDIRECT --to-ports 9040
-A PREROUTING -i eth1 -p udp -j REDIRECT --to-ports 9040
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT

 Make sure that the SSH-client can access the TorBox after the restart:

# Execute the following commands:
sudo systemctl unmask ssh
sudo systemctl enable ssh
sudo systemctl start ssh
11. Adding the user “torbox” and disabling the user “pi”

In this step the user “torbox” with the default password “CHANGE-IT” (or whatever you chose) is created. To use TorBox, you have to log in with “torbox” and the default password. Please, change all default passwords as soon as possible . The associated menu entries are placed in the configuration sub-menu.

We also disable the user “pi”.

cd
sudo adduser --gecos "" torbox
sudo adduser torbox sudo
sudo mv /home/pi/* /home/torbox/
sudo mv /home/pi/.profile /home/torbox/
sudo mkdir /home/torbox/openvpn
sudo rm .bash_history
sudo chown -R torbox.torbox /home/torbox/
sudo printf "\n# Added by TorBox\ntorbox  ALL=NOPASSWD:ALL\n" | sudo tee -a /etc/sudoers
sudo visudo -c
cd /home/torbox/

# Disabling "pi". This can be undone by sudo chage -E-1 pi
sudo chage -E0 pi

# Removing "pi"
sudo userdel -r pi
12. Restart your system
# Execute the following command
sudo reboot

After restarting your system, choose the preferred connection setup and change the default passwords as soon as possible. Check if your data stream is routed through the Tor network: https://check.torproject.org

For more information about TorBox, take a look at our documentation.