Internet access for the paranoid

There are certain situations where you just want to be sure to access the web in a secure and anonymous way. Most people are aware of the Tor (onion router) project and it’s software, there are plenty of tutorials in the web which help to get it up and running. There’s nothing wrong about that, or?

The basic setup is most often Tor + Privoxy + Firefox + Firebutton (+ Vidalia sometimes) and it works. It becomes a little uncomfortable when you want to use another application, for which you have to set the new proxy (being it Tor for SOCKS or Privoxy for HTTP or DNS queries) which does not always work as expected. And you have to be faithful into your apps to respect your settings in all circumstances!

When running Wireshark to monitor what packets are actually leaving your PC it becomes clear that this is not the best solution. To get real security we have to go a bit further down your software stack. I’m going to describe how to setup your free software box with Tor as a transparent proxy on kernel level. This setup will guarantee almost perfect security on the protocol level because your operating system kernel will take care with the extra bonus that yo have to setup exactly zero applications to have it work. So how does it work? Basically your applications access the net as normal, but the kernel (who is responsible to send/receive packages) won’t allow to just let the application packages pass into the net but instead resends it into the userspace to the Tor daemon which then sends the packets over the onion network. The nice thing is that newer Tor versions can be configured to act as a local nameserver (important for avoiding DNS query leakage), so where basically routing everything through Tor what is supported and drop the rest!

Here’s how it works, I assume a Debian-based running Linux box, iptables and Tor installed and that you’re using NetworkManager for painless network setup. The concept also works on Mac OS X and the BSD’s but I’m not really into their packet filter configuration (ipfw and pf).

First of all we have to tweak Tor’s configuration a bit, fire up your favorite editor and modify torrc (usually to be found under /etc/tor/torrc) like this:

SocksPort 9050 # what port to open for local application connections
SocksListenAddress # accept connections only from localhost

AutomapHostsOnResolve 1
Transport 9040
DNSPort 53

And restart your Tor daemon to apply the changes:

$ sudo /etc/init.d/tor restart

Fine, not that complicated after all, feel free to read the Tor documentation to fully understand what’s going on. The next question is how to make the kernel redirecting all packages through Tor? I already mentioned packet filtering and that’s our way to go. The Linux kernel with it’s beautiful Netfilter framework (and iptables userland tool) makes it easy to accomplish our task. But we’re going to add a little twist. I don’t want to have static iptabels rules set all the time, I want to have it only when I’m using NetworkManager and only if I’m connected to a net. You already guessed it, we need a little script which is executed when NetworkManager successfully connected to a net (and also when it disconnects). The NetworkManager allows the user to write so called ‘dispatcher-scripts’ which exactly do what we want and which have to be placed under /etc/NetworkManager/dispatcher.d/. Without further hazzle, here it is:


if [ -z “$1” ]; then
echo “$0: called with no interface” 1>&2
exit 1;


case “$2” in
## The following line is bonus for the paranoid!
#macchanger -r $IFACE

iptables -F
iptables -t nat -F

iptables -P INPUT DROP
iptables -A INPUT -p tcp -m state –state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -d -j ACCEPT
#iptables -A INPUT -p icmp -j ACCEPT

iptables -t nat -A OUTPUT -m owner –uid-owner “debian-tor” -j RETURN
#iptables -t nat -A OUTPUT -d -j RETURN # private network of class A
#iptables -t nat -A OUTPUT -d -j RETURN # private network of class B
#iptables -t nat -A OUTPUT -d -j RETURN # private network of class C
#iptables -t nat -A OUTPUT -d -j RETURN # private network (link local)
iptables -t nat -A OUTPUT -p tcp -d -j REDIRECT –to-ports 9040
iptables -t nat -A OUTPUT -d -j RETURN
#iptables -t nat -A OUTPUT -p icmp -j RETURN
iptables -t nat -A OUTPUT -p udp –dport 53 -j REDIRECT –to-ports 53
iptables -t nat -A OUTPUT -p tcp –syn -j REDIRECT –to-ports 9040

iptables -P OUTPUT DROP
iptables -A OUTPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -d -j ACCEPT
#iptables -A OUTPUT -p icmp -j ACCEPT
iptables -A OUTPUT -m owner –uid-owner “debian-tor” -j ACCEPT
iptables -A OUTPUT -j REJECT

## Prepend nameserver localhost ( to /etc/resolv.conf
#sed -n ‘1,1i\nameserver’ /etc/resolv.conf > /tmp/resolv.conf
#mv /tmp/resolv.conf /etc/resolv.conf
echo “nameserver” > /etc/resolv.conf
## Erase nameserver localhost ( from /etc/resolv.conf
#sed -n ‘1,1d’ /etc/resolv.conf
echo “” > /etc/resolv.conf

iptables -F
iptables -t -nat -F
iptables -P INPUT ACCEPT
echo “$0: called with unknown action \`$2′” 1>&2
exit 1

I recommend saving it as /etc/NetworkManager/dispatcher.d/02tor_transparent_proxy Where the leading number defines the script execution order (there is already a script starting with 01). We’re basically telling the kernel to drop everything (incomming, outgoing) per default, with the following exeptions for incomming packts:

  • Already established connections (previously by you)
  • Localhost packets (important!)

All the rest is dropped. We allow the following outgoing packets:

  • Already established connections
  • Localhost packets
  • Everything from Tor

The most complicating rules are those regarding network address translation (NAT). This basically controls how the kernel redirects packets to Tor. Where basically doing the following:

  • Don’t modify localhost packages
  • Send all DNS request (UDP port 53) back to Tor
  • Send all TCP packets back to Tor
  • Drop all the rest

There are some lines commented out, some of them allow un-torified communication inside your LAN and another set of rules which allow ICMP packets (to which ping packets belong to). Please have a look at the ipfilter documentation for further in-depth explanation. Please note that we are overwriting /etc/resolv.conf with the one and only localhost nameserver to allow DNS lookup only through Tor. There is also another extra line for the extra-paranoid (like me) which changes your IP-adress every time you connect to a network (needs the macchanger tool which is part of the aircrack-ng tool-suite).

Finally if where disconnecting from a network we’re restoring the old rules (none). When you’re now checking your IP traffic with Wireshark you should see no unencrypted packages, only TCP (with the exception of ARP packets and other net setup noise). Have fun!

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.