
Using Tor helps take back control of what data one decides to share online. It
also helps in avoiding surveillance from the local network (think of someone
listening to the public Wi-Fi) or the Internet access provider. But it is easy
to make mistakes:
Tor
Browser, the easiest and
most common way to use Tor, is just a web browser. Extra special care is
required to make other applications use Tor, and it is easy to forget to change
settings, let alone actual attackers.
That's why using
Tails is often recommended as
everything is preconfigured and it requires traffic to go through Tor by
various means.
Qubes or
Whonix also have interesting properties, but require
reinstalling systems and changing habits. Meanwhile, securing the network on an
already installed system can help you feel better.
A potential solution to prevent connections from
leaking out without going
through Tor is simply to prevent all connections from leaving the computer,
except the ones going to the Tor network. This can quite easily be implemented
by setting up an
outgoing firewall.
Using the default settings, a Tor client can potentially connect to any of the
2,000 Guard relays. While there are ways to get such a list and turn it
into firewall rules, we are going to use an easier solution.
Because the list of Tor relays is public, censors have often used it to
prevent people from connecting to the Tor network. The Tor project came
up with
bridges as a work-around. Bridges are entry nodes in the Tor
network. For public bridges, users can only get a few bridge addresses at a
time, preventing an adversary from easily blocking them at all once.
When configured to use a set of bridges, Tor will only connect to their
addresses. This will make our firewall much shorter.
The instructions that follow should work on Debian Jessie and later versions.
Adapting them to other systems should not be too hard either. We assume that
Tor Browser is already installed. As we will want other applications to
use Tor than just the browser, we also want to install a system-wide instance:
# apt install tor
Next, visit
bridges.torproject.org to request a set of bridges:

You then need to select the type of bridges. Tor standard protocol is easy
to identify as such. The Tor project has developed
pluggable transports to easily disguise the traffic, but using them is outside the scope for this documentation. So lets stay with the default type of bridges:

After solving a CAPTCHA, you'll get a list of addresses and fingerprints for a couple of bridges like the following one:

To tell Tor to use these bridges, edit
/etc/tor/torrc, and at the end, add something like:
UseBridges 1
Bridge 109.XXX.XXX.XXX:4XXX 2244XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Bridge 37.XXX.XXX.XXX:1XXXX 9CF0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Bridge 171.XXX.XXX.XXX:4XXX 7705XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Replace the actual addresses and fingerprints by those you got earlier.
Now reload the daemon and make sure that it still connects to the network:
# service tor reload
# tail -f /var/log/tor/log
Tor Browser also needs to be told to use these bridges. Open the onion menu
close to the location bar, and select
Tor Network Settings .

In there, tick
My Internet Service Provider (ISP) blocks connections to the
Tor network and paste the list of bridges below
Enter custom bridges:

Before we restrict outgoing connections to only use the Tor network, lets
configure APT to use Tor as well so we can continue installing and upgrading
packages in the future:
# apt install apt-transport-tor
The following command will reconfigure APT to use Tor to access the currently
configured package repositories. It basically takes care of replacing every
http:// by
tor+http://:
# sed -e 's/^[^#]*\(deb\(-src\)\?\W\+\)http/\1tor+http/' -i /etc/apt/sources.list /etc/apt/sources.list.d/*.list
Lets see if it still works:
# apt update
One last thing: sometimes, we still need to bypass our restrictions and access
the network directly. Some websites sadly deny access to Tor users, or we
might need to login through a
captive portal before being able to use a random network. To make it practical, we are going to create a new user account. This will enable us to use the desktop user switching capabilities to start a new browser or
sudo for command line applications. In this example, the user is going to be named
passthrough:
# adduser passthrough
Make sure to set a proper password!
Now lets configure the firewall. Here we are going to use
ferm which makes it fairly easy to do low-level firewall rule in a readable manner:
# apt install ferm
We want the firewall to be started at boot time. Now edit its configuration
in
/etc/ferm/ferm.conf. At the end, add:
# Let's block everything for both IPv4 and IPv6, except to localhost,
# already established connections and the special 'passthrough' user.
domain (ip ip6) chain OUTPUT
policy DROP;
outerface lo ACCEPT;
proto icmp ACCEPT;
mod state state (ESTABLISHED RELATED) ACCEPT;
mod owner uid-owner "passthrough" ACCEPT;
# Now for IPv4, we want to restrict output to configured Tor bridges
domain ip chain OUTPUT
# Don't break network autoconfiguration
mod owner uid-owner 0 proto udp dport bootps ACCEPT;
# Allow bridges defined in torrc by getting them directly
# from the configuration file.
@include "sed -n -e 's/^Bridge \([^ ]* \)\?\([0-9.]*\):\([0-9]*\).*/daddr \2 proto tcp dport \3 ACCEPT;/p' /etc/tor/torrc ";
# Let's REJECT everything else so we get notice instead of timeouts
domain (ip ip6) chain OUTPUT REJECT;
Reload the firewall through:
# service ferm reload
Lets do some tests:
# ping check.torproject.org
ping: unknown host check.torproject.org
# tor-resolve check.torproject.org
38.229.72.22
# ping 38.229.72.22
From 192.168.7.234 icmp_seq=1 Destination Port Unreachable
# curl https://check.torproject.org/
curl: (6) Could not resolve host: check.torproject.org
# curl -I https://38.229.72.22/
curl: (7) Failed to connect to 38.229.72.22 port 443: Connection refused
# curl --socks5 127.0.0.1:9050 https://check.torproject.org/
curl: (6) Could not resolve host: check.torproject.org
# curl --silent --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/ grep Congratulations
Congratulations. This browser is configured to use Tor.
# sudo -u passthrough ping -c 1 check.torproject.org
64 bytes from sergii.torproject.org (38.229.72.22): icmp_seq=1 ttl=54 time=148 ms
# sudo -u passthrough curl --silent https://check.torproject.org/ grep Sorry
Sorry. You are not using Tor.
One last thing to complete the setup: for command line applications like SSH,
torsocks does wonders. Just prefix your usual commands by
torsocks and
they should work:
# apt install torsocks
# torsocks curl --silent https://check.torproject.org/ grep Congratulations
Congratulations. This browser is configured to use Tor.
All set! In case you ever need to turn it all off, just ask
ferm to
reconfigure the firewall:
# service ferm stop
But don't forget to turn it back on later!
# service ferm start
Ideally, we would have a way to automatically configure a different set
of bridges for each network we connect to make it more difficult to trace
the computer from network to network. But there's quite some more work
to be done on various levels before that can be done in an integrated manner
(
torshiftchange and
tordyguards are promising options).
Meanwhile, be aware that you might want to keep a fresh set of bridges
handy to configure them after leaving for a trip.
Another downside of the setup currently is that it doesn't allow for
network time synchronization. That might make the system fingerprintable by
using its clock drift.
To use
obfs4 bridges which helps defeating censored networks, you will need
two extra steps. First, install the required software:
# apt install obfs4proxy
Then add the following extra line to
/etc/tor/torrc:
ClientTransportPlugin obfs2,obfs3,obfs4,scramblesuit exec /usr/bin/obfs4proxy
You can then request
obfs4 bridges from BridgeDB. These changes are only
required for the system-wide Tor daemon, as Tor Browser comes with
obs4proxy preconfigured.
Kudos to Micah for proofreading this article.