Recently I needed to route the traffic of a application through Tor, but said did not support any kind of proxy. So I decided to simply rout all traffic coming from the machine running the app through Tor. To accomplish this I used redsocks a tool to redirect TCP connections to a SOCKS/HTTPS proxy using iptables.

Setup

The setup consists of 2 VMs one acting as the Tor router and the other running the application to be tunnled through Tor.

VM0

The router vm named rtr01, has 2 network interfaces eth0 and eth1. eth0 is connected to the Hypervisor via NAT or Bridge, this interface must be able reach the internet to connect a Tor circuit. eth1 is connected to a virtual switch without internet access.

The router will be configured to act as default gateway for any connected machine and relay the connection through a Tor circuit.

VM1

The application host vm named app01, has only 1 network interface eth0. eth0 is connected to the same virtual switch as eth1 of vm0.

The application host will be connected to the router and use it as default gateway for connection to the internet, that will be relayed through a Tor circuit.

UDP/DNS

Whilst redsocks can be configured to relay UDP traffic for specific destination addresses and ports this is as of writing not supported by tor. This poses a problem for DNS as it is typically UDP:53. The traditional approach of getting DNS to work with redsocks is to use the redsocks internal UDP DNS server that only returns TURNCANATED which should trigger the resolution through TCP. However I found this to be rather unreliable, therefore I opted to use simply use the Tor built-in resolution of DNS.

Configuration

rtr01

The router should be a default fresh install of Debian 10. First off update and install the required packages on the machine.

# apt-get update
# apt-get dist-upgrade -y
# apt-get install -y iptables redsocks tor iptables-persist

The installer should already have configured eth0 as the default interface using DHCP. Next of eth1 will be configured so that the machine can be reached on the virtual switch.

Network

Network range: 192.0.2.0/24 TEST-NET-1

/etc/network/interfaces

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

# The WAN network interface
allow-hotplug eth0
iface eth0 inet dhcp

# The LAN network interface
allow-hotplug eth1
iface eth1 inet static
        address 192.0.2.1
        netmask 255.255.255.0
        network 192.0.2.0
        broadcast 192.0.2.255

Tor

The tor configuration is strait forward as only 2 settings are needed.

# Bind socks proxy on port 9050 of the LAN interface.
SocksPort 127.0.0.1:9050
# Bind dns on port 53 of the LAN interface.
DNSPort 192.0.2.1:53

Tor needs to bind the DNS port to the LAN interface as iptables only redirects the port.

Redsocks

In the redsocks config only the base and a single redsocks section are required. The base section is the Debian default config. And the redsocks section simply redirects all traffic from port 12345 to the Tor socks proxy on port 9059.

base {
        log_debug = off;
        log_info = on;
        log = "syslog:daemon";
        daemon = on;
        user = redsocks;
        group = redsocks;
        redirector = iptables;
}

redsocks {
        // Must bind on the LAN interface as iptables only redirects the ports.
        local_ip = 10.8.42.1;
        local_port = 12345;
        ip = 127.0.0.1;
        port = 9050;
        type = socks5;
}

iptables

First of create a new chain for redsocks, dropping reserved addresses and redirecting everything else to redsocks/tor. Unfortunately redoscks currently does not support IPv6.

# iptables -t nat -N REDSOCKS
# iptables -A REDSOCKS -d 0.0.0.0/8 -j RETURN
# iptables -A REDSOCKS -d 10.0.0.0/8 -j RETURN
# iptables -A REDSOCKS -d 127.0.0.0/8 -j RETURN
# iptables -A REDSOCKS -d 169.254.0.0/16 -j RETURN
# iptables -A REDSOCKS -d 172.16.0.0/12 -j RETURN
# iptables -A REDSOCKS -d 192.168.0.0/16 -j RETURN
# iptables -A REDSOCKS -d 224.0.0.0/4 -j RETURN
# iptables -A REDSOCKS -d 240.0.0.0/4 -j RETURN
# iptables -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345

To redirect all TCP connection coming in on eth1 to Tor the following PREROUTING rule is applied.

# iptables -A PREROUTING -s 192.0.2.0/24 -p tcp -j REDSOCKS

Redirect DNS requests to TOR.

# iptables -A PREROUTING -s 192.0.2.0/24 -p udp --dport 53 -j REDIRECT --to-ports 53

Finally safe the ruleset.

# iptables-save > /etc/iptables/rules.v4

Afterword

One disadvantage of this approach is that there is no way for a client to instruct Tor to establish a new circuit in case the current one is compromised, this could however be remedied by periodically switching the circuit.