Menu

Home

John Finlay

Overview

Torfilter is a package for OpenWRT that can be used to create iptables rules in order to route specific traffic through a Tor transparent proxy.

The main aim of Torfilters is not to provide complete anonymity to all sites (although it can be configured to do so). It's primary purpose is to anonimise (or geo-relocate) access to only to specific sites while leaving the remaining traffic to be routed as normal.

Torfilter configuration works by allowing the user to define multiple zones. A zone consists of a list of one or more interfaces and any number of host and/or range filters that should be applied to traffic being routed through those interfaces.

Package Installation

The packages can be found at https://sourceforge.net/projects/torfilter/files/packages/ (currently only ar71xx).

As Torfilter is not on the OpenWRT package feed the package must be downloaded manually before it can be installed. The following are the commands to download the ar71xx version of the package and install it.

wget http://sourceforge.net/projects/torfilter/files/packages/torfilter_1.0.0-1_ar71xx.ipk
opkg install torfilter_1.0.0-1_ar71xx.ipk

There are currently two versions of Tor in the main feed for Attitude Adjustment, the release version and an alpha version. The package is configured to install the release version as I'm don't like automatically installing non-release software (especially alpha software). I've had some issues with slow/intermittent access when using the release version that seem to be fixed in the alpha. If you experience problems you may want to try switching version.

Once the package has been installed you should reboot the device to enable the iptables modules.

Manual Installation

Dependencies

The following installs an iptables mod that allows packets to be be redirected. This is used by Torfilter to pass filtered packets to the Tor proxy & DNS ports.

opkg install iptables-mod-nat-extra

The following installs an iptables mod that allows packet filtering based on the contents of the packet. This is used by Torfilter to identify DNS requests that should be routed through Tor.

opkg install iptables-mod-filter

The following installs the ip command. This is used by Torfilter to retrieve local interface addresses. When filtering connections from local network ranges it allows exceptions to be made so connections to the gateway (such as ssh) are resolved in the normal manor.

opkg install ip

The following installs the hostname command. This is used by Torfilter to retrieve the local domain name. When filtering DNS requests it allows exceptions to be made so requests for local network hosts can be resolved by the gateway in the normal manor.

opkg install net-tools-hostname

There are currently two versions of Tor in the main feed for Attitude Adjustment, the release version and an alpha version. Which you use is up to you, the configuration for both is identical. I've had some issues with slow/intermittent access when using the release version that seem to be fixed in the alpha so you may want to use it. The following command will install the release version, if you want to try the alpha version you can replace "tor" with "tor-alpha".

opkg install tor

The following commands will start Tor and configure it to start when the system boots. Before you do this you should configure Tor (see "Tor Configuration" section for details).

/etc/init.d/tor start
/etc/init.d/tor enable

Finally the device should be rebooted in order enable the iptables modules.

Optional Packages

The following installs the GeoIP database. This package is not required for Torfilter to function however you will need it if you want to use Tor for geo-relocation (see Tor Configuration for details).
Important: This package is very large by OpenWRT standards (4.2MB at time of writing). If you are just using internal flash for data storage you probably don't want this

opkg install tor-geoip

Torfilter Install

The latest version of the Torfilter source can be downloaded from SourceForge using the following command.

git clone git://git.code.sf.net/p/torfilter/code torfilter

The following will install the Torfilter service and register it with the system. The ucitrack entry is required to make LuCI restart the service when it modifies the config file.

cp torfilter/src/etc/init.d/torfilter /etc/init.d/

uci add ucitrack torfilter
uci set ucitrack.@torfilter[-1].init=torfilter
uci commit ucitrack

The source code contains an example configuration file. The following command will copy that file into the systems config directory. If you want to create the file from scratch you can skip this step.

cp torfilter/src/etc/config/torfilter /etc/config/

The following will install the firewall include script and register it with the system. This allows the iptables rules to be re-create if the firewall is restarted.

mkdir /usr/share/torfilter
cp torfilter/src/usr/share/torfilter/firewall.include /usr/share/torfilter/

uci set firewall.torfilter=include
uci set firewall.torfilter.path=/usr/share/torfilter/firewall.include
uci commit firewall 

The following will install the LuCI web interface. If you are not going to use the web interface you can skip this step.

mkdir /usr/lib/lua/luci/controller/torfilter
cp torfilter/src/usr/lib/lua/luci/controller/torfilter/torfilter.lua /usr/lib/lua/luci/controller/torfilter/

mkdir /usr/lib/lua/luci/model/cbi/torfilter
cp torfilter/src/usr/lib/lua/luci/model/cbi/torfilter/torfilter.lua /usr/lib/lua/luci/model/cbi/torfilter/

Once installed the service can be started with the following.

/etc/init.d/torfilter start

If you want the service to start when the system boots the following command can be used.

/etc/init.d/torfilter enable

Tor Configuration

Torfilter doesn't support automatic configuration of Tor, it's the safe option as I didn't want to nuke an existing setup that had been lovingly hand crafted. The default location of the Tor configuration file is /etc/tor/torrc.

In order for Torfilter to be able to route connections you must configure Tor to run a transparent proxy. You will need a TransListenAddress entry for 127.0.0.1 so the gateway can use the service and you'll need an entry for each interface that is to to be used (192.168.1.1 in this example).
Important: You should NOT tell it to open a port on your WAN interface, the firewall should protect you but best not to risk it

TransPort 9040
TransListenAddress 127.0.0.1
TransListenAddress 192.168.1.1

In order for Torfilter to be able to route DNS requests you must configure Tor to run a DNS server. You will need a DNSListenAddress entry for 127.0.0.1 so the gateway can use the service, you'll also need an entry for each interface that is to use it (192.168.1.1 in this example).
Important: You should NOT tell it to open a port on your WAN interface, the firewall should protect you but best not to risk it

DNSPort 9053
DNSListenAddress 127.0.0.1
DNSListenAddress 192.168.1.1

If you want to allow clients to access Tor .onion sites you'll need the following entries. AutomapHostsOnResolve enables the resolving of the addresses and VirtualAddrNetwork defines the virtual IP range that Tor will use for these sites. Torfilter will create iptables rules that will route traffic to and from the range.

AutomapHostsOnResolve 1
VirtualAddrNetwork 10.192.0.0/10

If you want to allow clients to specify the exit node to be used for a connection with the virtual .exit domain, as well as the previous lines for .onion sites, you'll also need the following entry. By default access to .exit sites is blocked.

AllowDotExit 1

The following entries configure Tor so it will not use exit nodes in specified counties. This can be used to perform geo-relocation with Tor, where blocking exit nodes in your won country will make you appear to be in another. GeoIPFile specifies the location of the GeoIP database (see Optional Packages), ExcludeExitNodes tells Tor which countries to avoid (the UK in this example) and StrictNodes tells Tor to enforce the list (by default it's more of a suggestion).

GeoIPFile /usr/share/tor/geoip
ExcludeExitNodes {gb},{uk}
StrictNodes 1

The following setting is totally optional. I've no idea how much writing to disk Tor will actually do but as a lot of systems are flash based enabling this may help reduce ware.

AvoidDiskWrites 1

Torfilter Configuration

The configuration of Torfilter can either be done using the devices web interface or by manually editing the configuration file. If you want to use the web page it can be accessed from the Network tab of the devices web interface. The structure of the page maps very closely to the structure of the configuration file so working out which field equates to which entry in the file should be pretty straight forward. If you want to do things manually you'll need to edit /etc/config/torfilter. When you've finished editing you can use the following to make Torfilter reload the configuration file.

/etc/init.d/torfilter reload

The configuration file is in UCI format with a single system section and multiple zone sections. The following is an example of a file that has two zones. The first zone is configured to filter all connections to www.example.com on interface lan1, the second is configured to filter all connections from the range 192.168.3.0/24 on lan2.

config system 'system'
    option proxyport '9040'
    option dnsport '9053'
    option virtualrange '10.192.0.0/10'
    option updatedelay '60'

config zone 'lan1'
    option enableonion '1'
    option enableexit '1'
    list interface 'lan1'
    option hostdns '0'
    list host 'www.example.com'

config zone 'lan2'
    option enableonion '1'
    option enableexit '1'
    list interface 'lan2'
    option rangedns '1'
    list range '192.168.3.0/24'
System Parameters

proxyport : This is used to specify which port Tor is using for it's transparent proxy. This should be set to the same value as TransPort in the Tor configuration file.

dnsport : This is used to specify which port Tor is using for it's DNS server. This should be set to the the same value as DNSPort in the Tor configuration file.

virtualrange : This is used to specify which range Tor is using for it's virtual range. If you want Torfilter to give access to .onion or .exit nodes this should be set to the same value as VirtualAddrNetwork in the Tor configuration file.

updatedelay : This is a complete hack, it's necessary because when booting the Tor daemon will still be getting into a running state when Torfilter is started. If Torfilter is configured to filter DNS requests through Tor it means the there is a high chance it's initial lookups will fail which will lead to traffic not being routed through Tor. The updatedalay can be set to a value (in seconds) which Torfilter will wait for to allow Tor to get started. After the timeout has elapsed Torfilter will perform an update to creating any missing rules. The value that should be used will be device dependent, I use 60 seconds on my TL-WDR3600 and I've never had any troubles. If the value 0 (or no value) is specified then no delayed update is performed.

Zone Parameters

interface : This is used to specify an interface that the zones rules should be applied to. A zone can be applied to multiple interfaces and an interface is also allowed to appear in more than one zone.

enableonion : This is used to allow clients to access Tor hidden services using the .onion pseudo-top-level domain. This option will be ignored if the virtualrange system parameters is not specified.

enableexit : This is used to allow clients to specify there Tor exit node using the .exit pseudo-top-level domain. This option will be ignored if the virtualrange system parameters is not specified.

host : This is used to specify a host domain name that should be filtered. Access to this host from all clients will be routed through Tor. A zone can have multiple hosts and a host can appear in multiple zones.

hostdns : This is used to specify if DNS requests for filtered hosts should also be routed through Tor. This option will be ignored if the dnsport system parameter is not specified. Unless you are paranoid about someone snooping on your DNS requests you are best to leave this turned off, see "Why filtering DNS through Tor is not perfect" for details.

range : This is used to specify a client IP range to be filtered. All traffic from that range will be routed through Tor.

rangedns : This is used to specify if DNS requests from filtered ranges should also be routed through Tor. This option will be ignored if the dnsport system parameter is not specified.

How It Works

Host Filters

In order to filter a specified host Torfilter first performs a DNS lookup for it. If the hostdns option is enabled for the zone this lookup will be performed using the Tor DNS service. For each IP address in the response a rule is added to redirect TCP traffic that is going to that address to Tor. The following is an example of the rule that would be added if the host resolved to 1.1.1.1.

iptables -t nat -A "torfilter_lan" -i "br-lan" -p tcp -d "1.1.1.1" --syn -j REDIRECT --to-ports "9040"

If the hostdns option is enabled for the zone a rule is also added to redirect DNS requests for the host to Tor. The following is an example of the rule that would be added if the host was www.example.com.

iptables -t nat -A "torfilter_lan" -i "br-lan" -p udp --dport 53 -m string --algo bm --hex-string "|03777777076578616d706c6503636f6d00|" -j REDIRECT --to-ports "9053"

This rule uses the iptables filter mod to filter packets that contain the specified string. Inside a DNS request the names of the hosts being requested are stored as sequences of labels each preceded by the size with a 0 size terminating the sequence. For www.example.com the structure can be thought of as 3www7example3com0. There are issues with DNS filtering in relation to host filters, see "Why filtering DNS through Tor is not perfect" for details.

Range Filters

In order to filter a specified IP range Torfilter adds a rule to redirect TCP traffic coming from that range to Tor. This rule contains an exception for traffic that is going to the gateways IP address, this means you can still get at services running on the gateway when Torfilter is running. The following is an example of the rule that would be added if the range was 192.168.1.0/24 and the gateways address was 192.168.1.1.

iptables -t nat -A "torfilter_lan" -i "br-lan" -p tcp -s "192.168.1.0/24" ! -d "192.168.1.1" --syn -j REDIRECT --to-ports "9040"

If the rangedns option is enabled for the zone a rule is also added to redirect DNS requests to Tor. An exception is added to this rule for the domain that is set on the gateway, this is done so if the gateway is also serving out local DNS for your network those requests will still be handled by the gateway. The following is an example of the rule that would be added if the range was 192.168.1.0/24 and the local domain was .example.com.

iptables -t nat -A "torfilter_lan" -i "br-lan" -p udp --dport 53 -s "192.168.1.0/24" -m string --algo bm ! --hex-string "|076578616d706c6503636f6d00|" -j REDIRECT --to-ports "9053"

Details of how the DNS packet matching works can be found in the host filter section. When its used here it relies on the fact the filter will match request for any host that ends in the search string, this means requests for abc.example.com will not be passed to Tor.

Tor .onion & .exit Filters

When Tor is resolving DNS request for virtual domains it returns IP addresses from it's virtual address range. After that any connections made to those virtual ranges through Tor will be directed to the correct node, in the case of .onion hosts its the node running the hidden service and in the case of .exit hosts it's the exit node to be used to access the site.

In order to allow hosts access to the Tor virtual range a rule is added that redirects all TCP traffic going to IP addresses in that range to Tor. The following is an example of the rule that would be added if the virtual range was 10.192.0.0/10.

iptables -t nat -A "torfilter_lan" -i "br-lan" -p tcp -d "10.192.0.0/10" --syn -j REDIRECT --to-ports "9040"

The following rules are added to redirect DNS requests for .onion and .exit hosts respectively.

iptables -t nat -A "torfilter_lan" -i "br-lan" -p udp --dport 53 -m string --algo bm --hex-string "|056f6e696f6e00|" -j REDIRECT --to-ports "9053"
iptables -t nat -A "torfilter_lan" -i "br-lan" -p udp --dport 53 -m string --algo bm --hex-string "|046578697400|" -j REDIRECT --to-ports "9053"

Details of how the DNS packet matching works can be found in the host filter section. When its used here it relies on the fact the filter will match request for any host that ends in the search string, this means requests for abc.onion will be passed to Tor.

Why filtering DNS through Tor is not perfect

This section only applies to host filters, range filters are not affected by the following issues.

The first issue is down to a combination of how Torfilter works and the way the contents of Tor DNS responses. The rules that Torfilter manages are only updated when the service is told to reload. In the case of host filters rules are created for all the IP addresses that the host resolved to at that point. The problem with using Tor perform this resolve is that it's DNS response will only ever contain a single IP address even if the hosts DNS record has more than that. This can lead to the situation where the rule has been created for one address but at some point after this Tor has started returning a different address to clients. If this does happen the traffic from the clients to the new IP address won't be routed through Tor. Which of the addresses from the list Tor does return seem reasonably consistent, this means the problem can be alleviated by setting up a cron job to reload the service every few minutes. This is not perfect however, even with the service reloading every minute I've still seen the problem occur.

The second issue is due to a limitation in how iptables can perform matches on packet contents (or possibly due to my limited knowledge of iptables). In order to see if a DNS packet matches a host filter and should be filtered a search is performed on the packet contents for the name in question. The problem is that there is no way for it to differentiate an exact match from a sub-string match. For example if you configure it to filter bar.com it will also filter DNS requests for foo.bar.com. Luckily due to the way the DNS packets store the label lengths before labels the same rule would not match foobar.com. It's important to note that this only applies to DNS requests and not other traffic. Sticking with the same example, connections made to foo.bar.com would not be routed through Tor unless they both happen to resolve to the same address.

FAQ

How can I test things are working?
A useful site for testing is http://torstatus.blutmagie.de/, it will tell you if access to the site went through the Tor network.

It's not working, how can I fix it?
I'll add to this list as I think of things.

  • Check that the Tor & Torfilter services are started (and set to start at boot), this isn't done automatically
  • Torfilter writes to the syslog so take a look

Host filters or range filters, which are best?
As with most things like this it depends on your needs. Range filters provide the best anonymity as they will route all TCP connections and DNS requests through Tor. The downside of this is that all the traffic will be limited by the speed of the Tor network, this could make things like large web downloads painful. Host filters have the opposite properties, only the traffic you specify will be routed through Tor so only it will be limited by the speed of the Tor network. The downside with host filters is they risk "leaking" if not setup correctly, for example if you add a filter for www.site.com but click a link that goes to downloads.site.com the connection for the link won't be routed through Tor (unless both names resolve to the same IP address).
So in short, if you're after anonymity you want a range filter but if you just want to get access to a few sites you ISP/government doesn't want you to see then host filters are probably the order of the day.

How do I access .onion sites
See the Tor Configuration and Torfilter Configuration sections for details on how to enable access to .onion sites. Once you have set it up you can test it by going to http://idnxcnkne4qt76tg.onion/, if everything is working you should see the Tor homepage.

Why does access through Tor slow down after a few days?
This seems to be an issue with the release version of Tor in the Attitude Adjustment main feed. Try removing the release version and installing the alpha version instead.

Legal Bit

Neither I nor Torfilter are in any way connected to the wonderful people who created Tor.

I am not responsible for any damage caused by the use of Torfilter be it physical, mental, financial, legal, metaphysical, conceptual or otherworldly.


Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.