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 “Bookworm” Lite (64-bit) (based on Debian 12 “Bookworm”) on a Raspberry Pi 3 (Model B / Model B+) or Raspberry Pi 4 Model B. TorBox should also work on a new Raspberry Pi 5, but we couldn’t verify this yet. However this manual should also work with the 32-bit version of the Raspberry Pi OS and with an older Raspberry Pi.

Download the TorBox GitHub repository

Before you create all configuration files by yourself: some of the below-mentioned configuration files are stored in the “etc” folder in our GitHub repository.

1. Prepare your system
  1. Download the latest version of Raspberry Pi OS “Bookworm” Lite (64-bit) or use the Raspberry Pi Imager and choose, under Operating System, Raspberry Pi OS (other), the Raspberry Pi OS Lite (64-bit) image. With the Raspberry Pi Imager, you can also setup a Hostname, SSH, WiFi AP, username (use torbox), and your preferred password for a headless installation.
  2. If you don’t use the Raspberry Pi Imager, then transfer the downloaded Raspberry Pi OS Lite image on an SD Card, for example, with EtcherTorBox needs at least a 8 GB SD Card.
  3. If asked, create a user torbox and remember the chosen password for later use.
  4. Log into your newly set up system as torbox and with your chosen password. Using another username could lead to error messages later on.
  5. 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 5 – L4), or TorBox doesn’t
    work because WiFi is blocked!!
    – Also, disable the auto-login feature (in raspi-config menu entry 1 – S5 – B1)
    – 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

An alternative way disable the auto-login feature is following command:

sudo raspi-config nonint do_boot_behaviour B1

To overcome cheap censorship during the installation, put some well known public name servers into /etc/resolv.conf:

sudo printf "nameserver 1.1.1.1\nnameserver 1.0.0.1\nnameserver 8.8.8.8\nnameserver 8.8.4.4\n" | sudo tee /etc/resolv.conf
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.
  • iptables, ipset -> administration tools for packet filtering and NAT.
  • tor-geoipd, python3-stem, apt-transport-tor -> gives access to the Tor network (tor will be installed later, see further below).
  • nyx -> a command-line monitor for Tor.
  • usbmuxd -> a socket daemon to multiplex connections from and to iOS devices (support for tethering with iOS devices).
  • dnsmasq -> DNS forwarder (necessary to deal with captive portals).
  • dnsutils, tcpdump, iftop, vnstat -> analytical and statistical network tools.
  • debian-goodies, apt-transport-https -> other necessary tools.
  • dirmngr -> GNU privacy guard – network certificate management service.
  • python3-pip -> necessary for Python 3.
  • python3-pil, imagemagick, tesseract-ocr -> necessary libraries and programs for bridges_get.py.
  • qrencode, nginx, basez -> necessary for Onion Services implementation.
  • ntpdate -> necessary to set the correct system time.
  • macchanger -> utility for manipulating the MAC address of network interfaces. Important: macchanger will ask for enabling an automatic change of the MAC address – REPLY WITH NO!
  • 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.
  • git -> distributed revision control system.
  • openvpn -> software that implements virtual private network.
  • ppp -> Point-to-Point Protocol
  • wiringpi -> PIN based GPIO access library written in C for the BCM2835, BCM2836 and BCM2837 SoC devices used in all Raspberry Pi. Needed for the support of the Sixfab Shields/HATs for cellular connections.
  • raspberrypi-kernel-headers dkms -> necessary to compile / install additional drivers

Install all necessary packages with the following command:

# Installation of standard packages
sudo apt-get -y install hostapd isc-dhcp-server usbmuxd dnsmasq dnsutils \
tcpdump iftop vnstat debian-goodies apt-transport-https dirmngr \
python3-pip python3-pil imagemagick tesseract-ocr ntpdate screen git \ 
openvpn ppp python3-stem raspberrypi-kernel-headers dkms \ 
nyx apt-transport-tor qrencode nginx basez iptables macchanger

# If you use a Debian distribution instead of Raspberry Pi OS, you may need to 
# install the following additional packages
apt-get -y install wget curl gnupg net-tools unzip sudo rfkill resolvconf

# If you use a Ubuntu distribution instead of Raspberry Pi OS, you may need to 
# install the following additional packages
apt-get -y install net-tools ifupdown unzip equivs rfkill iw

# Installation of developper packages - THIS PACKAGES ARE NECESARY FOR THE 
# COMPILATION OF TOR!! Without them, tor will disconnect and restart every 
# 5 minutes!!
sudo apt-get -y install build-essential automake libevent-dev libssl-dev \
asciidoc bc devscripts dh-apparmor libcap-dev liblzma-dev libsystemd-dev \
libzstd-dev quilt zlib1g-dev

# IMPORTANT tor-geoipdb installs also the tor package. In an authoritarian 
# country, you may mask tor and activate it later with OBFS4 bridge support 
# to hide the use of tor.
sudo systemctl mask tor
sudo apt-get -y install tor-geoipdb
sudo systemctl mask tor
sudo systemctl stop tor

# Installation of wiringpi
wget https://project-downloads.drogon.net/wiringpi-latest.deb
sudo dpkg -i wiringpi-latest.deb
# Not nice, but working
sudo apt -y --fix-broken install
sudo dpkg -i wiringpi-latest.deb
sudo rm wiringpi-latest.deb

# Installation of needed Python modules
# Enable the possibility to manage Python modules with pip3
sudo rm "/usr/lib/python3.11/EXTERNALLY-MANAGED"

# Download and install the requirements
wget --no-cache https://raw.githubusercontent.com/radio24/TorBox/master/requirements.txt
sudo pip3 install -r requirements.txt

# ATTENTION
# In case of problems installing opencv-python-headless, try the following 
# command instead (thanks to airgap0, see here: https://github.com/radio24/TorBox/issues/209):
sudo apt install python3-opencv

# Installation of go 
#
# ATTENTION
# For a Raspberry Pi OS 32bit, you must use go1.20.5.linux-armv6l.tar.gz 
# (with a l like LIMA and not with a one (1)). Also, see here for all the 
# different packages depending on the hardware and the operating system:
# https://go.dev/dl/
cd ~
sudo rm -rf /usr/local/go
wget https://golang.org/dl/go1.20.5.linux-arm64.tar.gz
sudo tar -C /usr/local -xzvf go1.20.5.linux-arm64.tar.gz
export PATH=$PATH:/usr/local/go/bin
sudo printf "\n# Added by TorBox\nexport PATH=$PATH:/usr/local/go/bin\n" | sudo tee -a .profile

# Create a folder "openvpn" for *.ovpn files
sudo mkdir /home/torbox/openvpn
sudo chown -R torbox:torbox /home/torbox/

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

sudo systemctl disable dnsmasq
sudo systemctl daemon-reload
3. Compiling, installing and configuring Tor

There are at least three ways to install Tor:

  1. From the Raspberry Pi OS itself: this has probably already happened with the installation of tor-geoipdb. This method is recommended in authoritarian countries. However, usually that installs an older long-term-supported version of tor.
  2. From the Debian repository of the TorProject: we don’t recommend to use this way because it doesn’t support 32bit ARM systems/OS anymore with a debian package.
  3. From the unofficial Tor repositories on GitHub: we recommend this method as the standard way to install tor on the TorBox (used below). If necessary, forks can be used as mirror sites.

First step: Compiling and installing a specific version of tor from the unofficial Tor repositories on GitHub
Select a specific tor version from the unofficial Tor repositories on GitHub (alpha versions are not recommended!) and copy the link for the .tar.gz file (right click on the little .tar.gz sign); you need that link for the wget command below.

wget https://github.com/torproject/tor/archive/refs/tags/<torversion>.tar.gz
tar xzf <torversion>.tar.gz
cd <torversion>
git init
git add *
git config --global user.name "torbox"
git config --global user.email "torbox@localhost"
git commit -m "Initial commit"
./autogen.sh
./configure
make
sudo make install
cd ..
sudo rm -r <torversion>
sudo mv /usr/local/bin/tor* /usr/bin 

Second step: Installation of obfs4proxy and Snowflake

# Installation of obfs4proxy
cd ~
git clone https://salsa.debian.org/pkg-privacy-team/obfs4proxy.git
export GO111MODULE="on"
cd obfs4proxy
go build -o obfs4proxy/obfs4proxy ./obfs4proxy
sudo cp ./obfs4proxy/obfs4proxy /usr/bin
cd ~
sudo rm -rf obfs4proxy
sudo rm -rf go*

# Installation of Snowflake
cd ~
git clone https://github.com/tgragnato/snowflake
export GO111MODULE="on"
cd ~/snowflake/proxy
go get
go build
sudo cp proxy /usr/bin/snowflake-proxy

cd ~/snowflake/client
go get
go build
sudo cp client /usr/bin/snowflake-client

cd ~
sudo rm -rf snowflake
sudo rm -rf go*

Third step: Configuring Tor

## This is the configuration file of Tor

## DON'T CHANGE THE FOLLOWING 20 LINES!
######################################################
## Configuration for TorBox

Log notice file /var/log/tor/notices.log
VirtualAddrNetworkIPv4 10.192.0.0/10
AutomapHostsSuffixes .onion,.exit
AutomapHostsOnResolve 1
TransPort 127.0.0.1:9040
TransPort 192.168.42.1:9040
#TransPort 192.168.43.1:9040
DNSPort 127.0.0.1:9053
DNSPort 192.168.42.1:9053
#DNSPort 192.168.43.1:9053
SocksPort 127.0.0.1:9050
SocksPort 192.168.42.1:9050
#SocksPort 192.168.43.1:9050
SocksPort 127.0.0.1:9052 IsolateDestAddr
SocksPort 192.168.42.1:9052 IsolateDestAddr
#SocksPort 192.168.43.1:9052 IsolateDestAddr
ControlPort 127.0.0.1:9051
#ControlPort 192.168.42.1:9051
#ControlPort 192.168.43.1:9051
HashedControlPassword 16:E68F16640ED8C0F7601F5AA3D229D8DFD8715623CB055577F9434F7FB7
DisableDebuggerAttachment 0
AvoidDiskWrites 1
#%include /etc/tor/torrc.exclude-slow

## THE CONFIGURATION OF THE ONION SERVICES STARTS HERE!
#######################################################
## This will configure the Onion Services (do not remove or change that line - this is an anchor)

## This will configure the Onion Service authorizations
#ClientOnionAuthDir /var/lib/tor/onion_auth

## THE CONFIGURATION OF THE BRIDGE RELAY STARTS HERE!
######################################################
## This will setup 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 TorBox053
#BridgeDistribution any

## TO OVERCOME A FIREWALL, START HERE!
## HOWEVER, USE IT ONLY, IF REALLY NECESSARY!
######################################################
## This will allow you to run Tor as a client behind a firewall with
## restrictive policies, but will not 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 accept *:443, accept *:80

## 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 meek_lite,obfs4 exec /usr/bin/obfs4proxy
#ClientTransportPlugin snowflake exec /usr/bin/snowflake-client

## Meek-Azure (do not remove or change that line - this is an anchor)
#Bridge meek_lite 192.0.2.18:80 BE776A53492E1E044A26F17306E1BC46A55A1625 url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com

## Snowflake (do not remove or change that line - this is an anchor)
#Bridge snowflake 192.0.2.3:80 2B280B23E1107BB62ABFC40DDCC8824814F80A72 fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=cdn.sstatic.net ice=stun:stun.l.google.com:19302,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478 utls-imitate=hellorandomizedalpn
#Specific Snowflake bridge for China
#Bridge snowflake 192.0.2.4:80 8838024498816A039FCBBAB14E6F40A0843051FA fingerprint=8838024498816A039FCBBAB14E6F40A0843051FA url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=cdn.sstatic.net ice=stun:stun.l.google.com:19302,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.net:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478 utls-imitate=hellorandomizedalpn
#Specific Snowflake bridge for Iran
#Bridge snowflake 192.0.2.3:80 2B280B23E1107BB62ABFC40DDCC8824814F80A72 fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 url=https://snowflake-broker.azureedge.net/ front=ajax.aspnetcdn.com ice=stun:stun.voip.blackberry.com:3478,stun:stun.altar.com.pl:3478,stun:stun.antisip.com:3478,stun:stun.bluesip.net:3478,stun:stun.dus.net:3478,stun:stun.epygi.com:3478,stun:stun.sonetel.com:3478,stun:stun.sonetel.net:3478,stun:stun.stunprotocol.org:3478,stun:stun.uls.co.za:3478,stun:stun.voipgate.com:3478,stun:stun.voys.nl:3478 utls-imitate=hellorandomizedalpn
#Specific Snowflake bridge for Turkmenistan
#Bridge snowflake 192.0.2.3:1 2B280B23E1107BB62ABFC40DDCC8824814F80A72 fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 url=https://snowflake-broker.torproject.net.global.prod.fastly.net/ front=cdn.sstatic.net ice=stun:206.53.159.130:3479,stun:94.23.17.185:3479,stun:217.74.179.29:3479,stun:83.125.8.47:3479,stun:23.253.102.137:3479,stun:52.26.251.34:3479,stun:154.73.34.8:3479,stun:185.125.180.70:3479,stun:195.35.115.37:3479 utls-imitate=hellorandomizedalpn

## IMPORTANT: Currently, Snowflake supports only one bridge line. If you uncomment several bridge lines, only the first will be used.

## OBFS4 bridges
##
## You have three ways to get new bridge-addresses:
## 1. Get them here https://bridges.torproject.org/
## 2. Or send an email to [email protected], using an address
##    from Riseup or Gmail with "get transport obfs4" in the body of the mail.
## 3. Via Telegram (official): https://t.me/GetBridgesBot ; then use /bridges to get a bridge.
## 4. (Not recommended, only if needed): Via Telegram (unofficial): https://t.me/tor_bridges

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 3.

Also, the tor installation has to be prepared for onion services:

sudo mkdir /var/lib/tor/services
sudo chown -R debian-tor:debian-tor /var/lib/tor/services
sudo chmod -R go-rwx /var/lib/tor/services
sudo mkdir /var/lib/tor/onion_auth
sudo chown -R debian-tor:debian-tor /var/lib/tor/onion_auth
sudo chmod -R go-rwx /var/lib/tor/onion_auth

Fourth step: Configuring geoip and obfs4proxy

# Execute the following commands:
sudo chmod a+x /usr/share/tor/geoip*
sudo cp /usr/share/tor/geoip* /usr/bin
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]
4. Installing the TorBox Menu (and download all configuration files)
Download the TorBox GitHub repository

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, a SSH-client (192.168.42.1 on a WiFi client or 192.168.43.1 on a cable client) or a web browser (http://192.168.42.1 on a WiFi client or http://192.168.43.1 on a cable client) access the TorBox. 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” and all configuration file under “~/torbox/etc”. 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/refs/heads/master.zip
unzip master.zip
mv TorBox-master torbox
rm -r master.zip

# Edit .profile:
sudo nano .profile

# Add the following lines to the end of ".profile":
cd torbox
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
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/usr/local/go/bin
sudo dmesg -D
rfkill unblock all
rfkill block bluetooth
bash /home/torbox/torbox/bin/regset
sudo systemctl stop hostapd

CHECK_OS="$(lsb_release -si)"
CHECK_OS="$(echo "$CHECK_OS" | tail -n1)"
if [ "$CHECK_OS" = "Ubuntu" ] ; then
	if ip -o link show | awk -F': ' '{print $2}' | grep end0 ; then
		# rename interface name from end0 to eth0
		# See also here: https://unix.stackexchange.com/questions/396382/how-can-i-show-the-old-eth0-names-and-also-rename-network-interfaces-in-debian-9
		sudo ip link set end0 down
		sudo ip link set end0 name eth0
	fi
fi

if grep "TWEBSSH=1" /home/torbox/torbox/run/torbox.run ; then
	[ ! -f /etc/nginx/sites-available/webssh.conf ] && sudo cp /home/torbox/torbox/etc/nginx/sites-available/sample-webssh.conf /etc/nginx/sites-available/webssh.conf
	[ ! -L /etc/nginx/sites-enabled/webssh.conf ] && sudo ln -sf /etc/nginx/sites-available/webssh.conf /etc/nginx/sites-enabled/
	(nohup sudo /home/torbox/torbox/lib/webssh/twebssh --unix-socket=/var/run/webssh.sock &) 2>/dev/null
	sudo ls /var/run | grep .*-onion-.*.sock | xargs -I {} -d"\n" sudo rm /var/run/{}
	sudo systemctl restart nginx
fi

# Change the MAC address if needed
# List all available network interfaces
AVAILABLE_INTERFACES=$(ip -o link show | awk -F': ' '{print $2}' | sed "/^lo/d" | sed "/^wwan/d")
for INTERFACE in $AVAILABLE_INTERFACES ; do
	if grep "^MAC_$INTERFACE=permanent" /home/torbox/torbox/run/torbox.run || grep "^MAC_$INTERFACE=random" /home/torbox/torbox/run/torbox.run ; then
		# NEW v.0.5.3: We have only to put an interface down, if it is not already down
		# ATTENTION not connected interfaces have to put down, even the state is already down --> NO-CARRIER
		if ip link | grep "$INTERFACE" | grep -e "state UP" -e "NO-CARRIER" ; then
			sudo ip link set dev $INTERFACE down
			INTERFACE1_DOWN=1
			sleep 2
		fi
		#
		if grep "^MAC_$INTERFACE=permanent" /home/torbox/torbox/run/torbox.run; then sudo macchanger -p $INTERFACE; fi
		if grep "^MAC_$INTERFACE=random" /home/torbox/torbox/run/torbox.run; then sudo macchanger -r $INTERFACE; fi
		# NEW v.0.5.3: We have only to put an interface up, if it was up before
		if [ "$INTERFACE1_DOWN" = "1" ]; then
			sudo ip link set dev $INTERFACE up
			INTERFACE1_DOWN=0
		fi
		#
	else
		MAC_ADDRESS=$(grep "MAC_$INTERFACE=" /home/torbox/torbox/run/torbox.run | sed "s/.*=//g")
		# NEW v.0.5.3: We have only to put an interface down, if it is not already down
		# ATTENTION not connected interfaces have to put down, even the state is already down --> NO-CARRIER
		if ip link | grep "$INTERFACE" | grep -e "state UP" -e "NO-CARRIER" ; then
			sudo ip link set dev $INTERFACE down
			INTERFACE1_DOWN=1
			sleep 2
		fi
		sudo ip link set dev $INTERFACE address $MAC_ADDRESS
		# NEW v.0.5.3: We have only to put an interface up, if it was up before
		if [ "$INTERFACE1_DOWN" = "1" ]; then
			sudo ip link set dev $INTERFACE up
			INTERFACE1_DOWN=0
		fi
	fi
done

# FAILSAFE: To set TorBox's AP to wlan1 is dangerous and may lock someone out. We change that back to wlan0.
if grep "WLAN_FAILSAFE=1" /home/torbox/torbox/run/torbox.run ; then
	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 sed -i "s/^INTERNET_IFACE=.*/INTERNET_IFACE=wlan1/" /home/torbox/torbox/run/torbox.run
  	sudo sed -i "s/^CLIENT_IFACE=.*/CLIENT_IFACE=wlan0 eth0/" /home/torbox/torbox/run/torbox.run
  	sudo ifup wlan0 &>/dev/null &
  	sudo ifup wlan1 &>/dev/null &
		sudo systemctl restart hostapd
		sudo systemctl restart isc-dhcp-server
		sleep 2
	fi
fi

sudo systemctl start hostapd

# If a wireless USB dongle is available, and previously used then let's check if we can auto-connect to a wireless network
if ip link | grep wlan1 ; then
  if grep "INTERNET_IFACE=wlan1" /home/torbox/torbox/run/torbox.run ; then
	  exitstatus=$(sudo /usr/bin/python3 /home/torbox/torbox/lib/torbox_wireless_manager.py -i wlan1 -a)
	fi
fi

# If the internal wlan chip was previously used then let's check if we can auto-connect to a wireless network
if grep "WLAN_FAILSAFE=0" /home/torbox/torbox/run/torbox.run ; then
	if ip link | grep wlan0 ; then
		if grep "INTERNET_IFACE=wlan0" /home/torbox/torbox/run/torbox.run ; then
			exitstatus=$(sudo /usr/bin/python3 /home/torbox/torbox/lib/torbox_wireless_manager.py -i wlan0 -a)
		fi
	fi
fi

# If a cellular device is available, and previously used then let's check if we can auto-connect
if grep "INTERNET_IFACE=ppp0" /home/torbox/torbox/run/torbox.run ; then pon ; fi

# Sometimes, connected to eth0 doesn't result in a default gateway (is this necessary for other interfaces, too?)
if ip link | grep eth0 ; then
	if grep "INTERNET_IFACE=eth0" /home/torbox/torbox/run/torbox.run ; then
		if ! sudo timeout 5 sudo route | grep -m 1 default; then
			sudo ifdown eth0 2>/dev/null
			ip addr flush dev eth0
			sudo ifup eth0 2>/dev/null
		fi
	fi
fi

# If configured, turn TACA on
if grep "LOGCHECK=1" /home/torbox/torbox/run/torbox.run ; then
  (nohup sudo /usr/bin/python3 /home/torbox/torbox/log_check.py &) 2>/dev/null
fi

# Start TFS and TCS, if configured
if grep "^TFS-" /home/torbox/torbox/run/torbox.run ; then sudo /home/torbox/torbox/bin/start_tfs initial ; fi
if grep "^TCS-" /home/torbox/torbox/run/torbox.run ; then sudo /home/torbox/torbox/bin/start_tcs initial ; fi

sudo systemctl start dnsmasq
sudo /bin/ping -c 1 "pool.ntp.org" >/dev/null 2>&1 && sudo /usr/sbin/ntpdate pool.ntp.org

# NEW v.0.5.3
# Starting domain exclusion, if activated
if grep "^UNPROTECTED_DOMAIN=1" /home/torbox/torbox/run/torbox.run ; then sudo /sbin/ipset -q restore -file /home/torbox/torbox/run/clearnet-list -exist ; fi
sudo /sbin/iptables-restore < /etc/iptables.ipv4.nat

# This function opens the ports, after a restart if bridge relay is on
if grep "^BridgeRelay" /etc/tor/torrc ; then
  ORPORT=$(grep "^ORPort" /etc/tor/torrc | cut -d " " -f2)
  OBFS4PORT=$(grep "^ServerTransportListenAddr" /etc/tor/torrc | cut -d ":" -f2)
  (sudo /sbin/iptables -C INPUT -p tcp --dport $ORPORT -j ACCEPT) 2>/dev/null
  RULE_CHECK=$?
  if [ $RULE_CHECK = 1 ]; then
    (sudo /sbin/iptables -A INPUT -p tcp --dport $ORPORT -j ACCEPT) 2>/dev/null
    (sudo /sbin/iptables -A INPUT -p tcp --dport $OBFS4PORT -j ACCEPT) 2>/dev/null
  fi
else
	if iptables-save | grep -e "-A INPUT -p tcp --dport $ORPORT -j ACCEPT" ; then (sudo /sbin/iptables -D INPUT -p tcp --dport $ORPORT -j ACCEPT) 2>/dev/null ; fi
	if iptables-save | grep -e "-A INPUT -p tcp --dport $OBFS4PORT -j ACCEPT" ; then (sudo /sbin/iptables -D INPUT -p tcp --dport $OBFS4PORT -j ACCEPT) 2>/dev/null ; fi
fi

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 [54313:2809534]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [1039297:768247214]
-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
COMMIT
*nat
:PREROUTING ACCEPT [73382:4436645]
:INPUT ACCEPT [37058:5368023]
:OUTPUT ACCEPT [607:54158]
:POSTROUTING ACCEPT [268:30614]
-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 -d 10.192.0.0/10 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports 9040
-A PREROUTING -p tcp -m tcp --dport 80 -j LOG --log-prefix "HTTP-REQUEST TCP " --log-tcp-options --log-ip-options
-A PREROUTING -p udp -m udp --dport 80 -j LOG --log-prefix "HTTP-REQUEST UDP " --log-ip-options
-A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination 0.0.0.0
-A PREROUTING -p udp -m udp --dport 80 -j DNAT --to-destination 0.0.0.0
-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
sudo systemctl daemon-reload
5. Setting up a DHCP server
# Set up your hostname (for example "TorBox" instead of "raspberrypi":
sudo hostnamectl set-hostname "TorBox"
sudo systemctl restart systemd-hostnamed
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;
6. 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
7. 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=TorBox053
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
8. 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"
9. Configuring Nginx to work with webssh and Onion Services

The default Nginx configuration works fine, but we have to allow uploads bigger than 1Mb. client_max_body_size 0 will remove any size limit. Of course, there is also the possibility to set another, bigger size limit than 1 Mb. Because of security considerations, we also recommend switching server_tokens to off, hiding the Nginx server version on error pages.

# Edit /etc/nginx/nginx.conf:
sudo nano /etc/nginx/nginx.conf

# Old entries:
client_max_body_size 1m;

# New entry:
client_max_body_size 0;
server_tokens off;

There is also an annoying behaviour of Nginx: it doesn’t remove the socket files in /var/run during a restart or when closing down. When starting again, Nginx is complaining because of these already existing socket files. Currently, in TorBox we deal with this fact in the script, are looking for unused socket files and deleting them. Neverthertheless we recommend implementing this change to the /etc/init.d/nginx, which is recommended here by using the following command:

sudo sed "s|STOP_SCHEDULE=\"${STOP_SCHEDULE:-QUIT/5/TERM/5/KILL/5}\"|STOP_SCHEDULE=\"${STOP_SCHEDULE:-TERM/5/KILL/5}\"|g" /etc/init.d/nginx

Also, we don’t need the example configuration and html file, but the configuration file for webssh:

sudo rm /etc/nginx/sites-enabled/default
sudo rm /etc/nginx/sites-available/default
sudo rm -r /var/www/html

# This is necessary for Nginx / TFS
sudo chown torbox:torbox /var/www

sudo cp etc/nginx/sites-available/sample-webssh.conf /etc/nginx/sites-available/webssh.conf
sudo ln -sf /etc/nginx/sites-available/webssh.conf /etc/nginx/sites-enabled/
10. 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

sudo rfkill block bluetooth

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

11. Update sudo setup
if ! sudo grep "# Added by TorBox" /etc/sudoers ; then
  sudo printf "\n# Added by TorBox\ntorbox  ALL=(ALL) NOPASSWD: ALL\n" | sudo tee -a /etc/sudoers
  (sudo visudo -c) 2> /dev/null
fi
12. Stop logging, preparing for the first start and restarting the system
# Preparing the system for the first start (we don't need nginx running if not needed)
sudo systemctl stop nginx

# To start TACA (TorBox Automatic Countermeasure Actions), notices.log has to be present
sudo -u debian-tor touch /var/log/tor/notices.log
sudo chmod -R go-rwx /var/log/tor/notices.log

# Stop logging
sudo systemctl stop rsyslog
sudo systemctl disable
sudo systemctl mask rsyslog
sudo systemctl stop systemd-journald-dev-log.socket
sudo systemctl stop systemd-journald-audit.socket
sudo systemctl stop systemd-journald.socket
sudo systemctl stop systemd-journald.service
sudo systemctl mask systemd-journald.service

# Remove log files and history
sudo rm /var/log/*
sudo journalctl --vacuum-size=1M
history -c

# This is not mandatory, but we recommend to start our image preparation script 
# (even if you don't make an image) to check the installation and perform some 
# routine cleaning tasks
cd /home/torbox/torbox
bash install/prepare_image.sh

# If you don't want to use our preparation script (prepare_image.sh) in TorBox 
# Menu's install folder, you have at least to set the right start trigger in torbox.run
# This is necessary for starting the "first use" configuration dialogue.
sudo sed -i "s/^FRESH_INSTALLED=.*/FRESH_INSTALLED=2/" /home/torbox/torbox/run/torbox.run

# Restart the system
sudo reboot

After restarting the system, connect your client to the new WiFi “TorBox053” (password: CHANGE-IT). Log into the TorBox by using a SSH client (192.168.42.1 on a WiFi client or 192.168.43.1 on a cable client) or a web browser (http://192.168.42.1 on a WiFi client or http://192.168.43.1 on a cable client; for a connection via cable, see here; username: torbox / and your chosen password). After seeing a welcome screen and answering some initial questions during the first start-up, you should see the TorBox Main Menu. Choose the preferred connection setup. Finally, change the default passwords as soon as possible (the associated entries are placed in the configuration sub-menu). Check if your data stream is routed through the Tor network: https://check.torproject.org