Transparent Tor-ifying VLAN (separated WLAN SSID) with OpenWRT

Why

Tor allows to anonymize Internet traffic through onion routing, typically via 3 separate hops. At INS, we run one of the fastest Tor exit nodes in Austria, and provide statistical data on its usage. For more details, please check those project websites.

On my personal home network, I use Tor - among other reasons - to test various devices such as mobile phones, tablets, etc. with apps I do not necessarily trust, “smart home” / IoT style devices, or wearables. By tunneling their Internet communication through Tor, both correlation with traffic on my upstream Internet connection becomes a lot harder and IP geo location is somewhat randomized, allowing test experience akin to running the devices in different countries.

How

These notes are a summary of my setup, with most of the inspiration taken from here. Please thank the Tor project for making this fairly easy already, and all mistakes in here are mine alone.

  1. opkg update
  2. opkg install tor
  3. Add a new VLAN in /etc/config/network:
```apache
config interface 'tor'
        option proto 'static'
        option ifname 'eth0.69'
        option ip6addr '<REPLACEWITHYOURPREFIX>::/64'
        option ipaddr '192.168.69.1/24'
        option type 'bridge'
        option bridge_empty '1'

config switch_vlan
        option device 'switch0'
        option vlan '8'
        option vid '69'
        option ports '0t 2t 3t'
```
In this version, I added both a VLAN for the on-board physical switch (here with VLAN ID 69, change as necessary) and a subnet definition connecting to this VLAN with both IPv4 and IPv6 addresses. The full switched VLAN allows to connect external WiFi access points with separate SSIDs bridged to this VLAN. While I personally use multiple UniFi UAP-AC PRO access points with roaming support in both 2.4Ghz and 5Ghz bands, pretty much any (semi-) professional gear will allow similar setups - including any hardware supported by OpenWRT/LEDE as long as the WiFi chipset firmware allows multiple concurrent SSIDs.

Note that this configuration block also makes the interface an internal bridge so that an internal WiFi interface can be directly attached if you only want to use one device instead of external access points.
  1. ifup tor
  2. /etc/init.d/tor enable
  3. Configure the Tor daemon through /etc/tor/torrc:
```apache
  # support transparent Tor-ifying traffic
  SOCKSPort 9050 # Default: Bind to localhost:9050 for local connections.
  SOCKSPolicy accept 192.168.0.0/16
  VirtualAddrNetwork 10.192.0.0/16
  AutomapHostsOnResolve 1
  TransPort 192.168.69.1:9040
  DNSPort 192.168.69.1:9053

  # general settings
  Log notice syslog
  Nickname DEFINITELYREPLACETHIS
  ExitPolicy reject *:* # no exits allowed

  # To be a good citizen to the Tor network, it is highly recommended to enable
  # at least the relay functionality if you can spare a bit of data volume.
  # If you want to act as a relay, enable these options here.
  #ORPort 9001
  #RelayBandwidthRate 1000 KBytes  # Throttle traffic to 1000KB/s (8Mbps)
  #RelayBandwidthBurst 2000 KBytes # But allow bursts up to 2000KB (16Mbps)
  #AccountingMax 15 GBytes
  #AccountingStart day 00:00
```
Note that this binds the transparent Tor ports `9040` (for TCP connections) and `9053` (for DNS resolution) to the IP address configured on this new network interface. You could potentially use `0.0.0.0` for listening on all interfaces, but then need to make sure that external traffic is blocked from using this node. Binding to only the specific address is safer. However, if you changed the IP address in `/etc/config/network`, use the same here.
  1. /etc/init.d/tor start

  2. If the setup only includes one access point on the same OpenWRT box, define it in /etc/config/wireless (here for the example of a Turris Omnia both for 2.4Ghz and 5Ghz radios with SSID ‘Tor’ and WPA2 PSK ’torifyme’, change as required):

```apache
config wifi-iface 'tor_iface_0'
      option disabled '0'
      option device 'radio0'
      option mode 'ap'
      option ssid 'Tor'
      option encryption 'psk2+tkip+aes'
      option key 'torifyme'
      option ifname 'tor_iface_0'
      option network 'tor'
      option isolate '1'

config wifi-iface 'tor_iface_1'
      option disabled '0'
      option device 'radio1'
      option mode 'ap'
      option ssid 'Tor'
      option encryption 'psk2+tkip+aes'
      option key 'torifyme'
      option ifname 'tor_iface_1'
      option network 'tor'
      option isolate '1'  
```
  1. Define a new DHCP subnet to be handed out on this subnet in /etc/config/dhcp: apache config dhcp 'tor' option interface 'tor' option start '200' option limit '50' option leasetime '1h' option ignore '0' list dhcp_option '6,192.168.69.1' Note that the local IP address for the tor interface configured in /etc/config/network is repeated here, handed out to DHCP clients as the DNS server address to use. If you change to a different network address above, also change here.

  2. /etc/init.d/dnsmasq reload

  3. Define a new firewall rules zones and allow selective traffic from that VLAN in /etc/config/firewall:

```apache
config zone
      option input 'DROP'
      option forward 'REJECT'
      option output 'ACCEPT'
      option name 'transtor'
      option network 'tor'
      option conntrack '1'

config rule
      option target 'ACCEPT'
      option proto 'udp'
      option dest_port '9053'
      option name 'Allow-Tor-from-Transtor'
      option src 'transtor'

config rule
      option target 'ACCEPT'
      option proto 'tcp'
      option dest_port '9040'
      option name 'Allow-Tor-from-Transtor'
      option src 'transtor'

config rule
      option target 'ACCEPT'
      option proto 'udp'
      option name 'Allow-Tor-DHCP'
      option src 'transtor'
      option dest_port '67'
```
  1. And now the final magic touch, which requires directly resorting to iptables in /etc/firewall.user: bash ############### Transparent Tor-ifying rules ########################## iptables -t nat -A prerouting_rule -i br-tor -p udp --dport 53 -j REDIRECT --to-ports 9053 iptables -t nat -A prerouting_rule -i br-tor -p tcp --syn -j REDIRECT --to-ports 9040 # when using tor on this box to resolve DNS requests, .onion addresses are translated to this range iptables -t nat -A prerouting_rule -d 10.192.0.0/16 -p tcp --syn -j REDIRECT --to-ports 9040

  2. fw3 restart

This will transparently redirect all TCP traffic as well as UDP traffic to specifically port 53 (i.e. DNS lookups) to the Tor daemon running locally. Tor then takes care of resolving DNS and queries tunneling TCP connections through Tor. Additionally, .onion DNS addresses are resolved to a configured private IP range, which the Tor daemon can then translate into traffic to hidden services even though the respective client has no notion of Tor itself.

Limitations

As may be obvious from this last point, this setup will not be able to tunnel UDP traffic (besides the special case of UDP resolution). Additionally, both performance (bandwidth and latency) and reliability of (TCP) connections will generally suffer. That is, any real-time scenarios like audio or video links will probably not be pleasant to use. However, any connections that can deal with increased latency and buffering are typically fine.

The above configuration also doesn’t yet support IPv6 proxying through Tor, so clients will simply not get IPv6 addresses for now.

Testing / Debugging

Any device connected to this new VLAN through the WiFi SSID or directly on the switch should now transparently tunnel its TCP connections through Tor. You can use services like this (which will promptly ask you to complete a Captcha when coming through Tor…) or many others including Google (which will most probably also ask to complete a Captcha when accessed through Tor) to check which IP address your device appears to use to the wider Internet.

If devices on this VLAN get no connection at all or do not transparently tunnel through Tor, I recommend debugging through:

  • Checking the system log (logread for standard OpenWRT/LEDE, tail -f /var/log/messages for the Turris version), which should show Tor startup messages and clients receiving DHCP assigned addresses on this subnet when they connect.
  • netstat -anp | grep tor to check the Tor daemon is running and listening on the configured addresses and ports.
  • iptables -t nat -L prerouting_rule -vn to check if packets coming in on that interface are transparently redirected to the local Tor daemon ports (pkts and bytes counters should be increasing).
  • tcpdump -n -i br-tor for the real deal ;-)
René Mayrhofer
René Mayrhofer
Professor of Networks and Security & Director of Engineering at Android Platform Security; pacifist, privacy fan, recovering hypocrite; generally here to question and learn