up to Tor

1. Transparently Routing Traffic Through Tor

Starting with version 0.1.2.1-alpha, Tor has support for transparent proxy connections in addition to SOCKS connections. With traditional proxy methods like SOCKS, setting up the proxy server itself isn't enough; proxy-supporting applications must be chosen, and each application on each machine using the proxy must be specially configured by the user or network administrator to connect through the proxy. Sometimes this isn't possible because an application doesn't support SOCKS, or the administrator doesn't want users to know their traffic is being sent through a proxy. These problems can be avoided by using your operating system's packet filtering facility to redirect outbound connections into a transparent proxy, so-called because its presence is intended to be invisible to clients.

This document details two common uses for Tor's transparent functionality. The first is routing all traffic on a standalone machine through Tor. Once this is set up, every network application will make its TCP connections through Tor; no application will be able to reveal your IP address by connecting directly. The second is creating an anonymizing middlebox that intercepts traffic from other machines and redirects it through Tor.

Since a transparent proxy operates without application support, we have to accept ordinary DNS requests and somehow resolve them through Tor in order to avoid anonymity compromising DNS leaks. Tor versions starting with 0.2.0.1-alpha have a built-in DNSPort designed to operate as a limited DNS server. A previous revision of this page contains instructions for 0.1.2.x versions of Tor.

Currently, transparent proxy connections are only supported for netfilter in Linux and pf in BSD.

Table of Contents

2. Linux (netfilter)

Required software:

Assumptions:

2.1. Transparently anonymizing traffic for a specific user

At first, we need to create a new user:

useradd -m anonymous

iptables rules:

iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner anonymous -m tcp --syn -j REDIRECT --to-ports 9040 
iptables -t nat -A OUTPUT -p udp -m owner --uid-owner anonymous -m udp --dport 53 -j REDIRECT --to-ports 53 
iptables -t nat -A OUTPUT -m owner --uid-owner anonymous -j DROP

torrc:

AutomapHostsOnResolve 1
TransPort 9040
DNSPort 53

Now you can run apps with sudo and they will be magically anonymized:

sudo -H -u anonymous irssi

2.2. Local Redirection Through Tor

To enable the transparent proxy and the DNS proxy add the following to your torrc.

AutomapHostsOnResolve 1
TransPort 9040
DNSPort 53

Configure your system's DNS resolver to use Tor's DNSPort on the loopback interface by modifying /etc/resolv.conf.

nameserver 127.0.0.1

Use the iptables ruleset below as an example.

#!/bin/sh

# destinations you don't want routed through Tor
NON_TOR="192.168.1.0/24 192.168.0.0/24"

# the UID Tor runs as
TOR_UID="109"

# Tor's TransPort
TRANS_PORT="9040"

iptables -F
iptables -t nat -F

iptables -t nat -A OUTPUT -m owner --uid-owner $TOR_UID -j RETURN
for NET in $NON_TOR 127.0.0.0/9 127.128.0.0/10; do
  iptables -t nat -A OUTPUT -d $NET -j RETURN
done
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 $TRANS_PORT

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
for NET in $NON_TOR 127.0.0.0/8; do
  iptables -A OUTPUT -d $NET -j ACCEPT
done
iptables -A OUTPUT -m owner --uid-owner $TOR_UID -j ACCEPT
iptables -A OUTPUT -j REJECT


2.3. Anonymizing Middlebox

To enable the transparent proxy and the DNS proxy, add the following to your torrc.

VirtualAddrNetwork 10.192.0.0/10
AutomapHostsOnResolve 1
TransPort 9040
TransListenAddress 192.168.1.1
DNSPort 53
DNSListenAddress 192.168.1.1

Use the iptables ruleset below as an example.

#!/bin/sh

# destinations you don't want routed through Tor
NON_TOR="192.168.1.0/24 192.168.0.0/24"

# Tor's TransPort
TRANS_PORT="9040"

# your internal interface
INT_IF="eth0"

iptables -F
iptables -t nat -F

for NET in $NON_TOR; do
  iptables -t nat -A PREROUTING -i $INT_IF -d $NET -j RETURN
done
iptables -t nat -A PREROUTING -i $INT_IF -p udp --dport 53 -j REDIRECT --to-ports 53
iptables -t nat -A PREROUTING -i $INT_IF -p tcp --syn -j REDIRECT --to-ports $TRANS_PORT


2.4. Local Redirection and Anonymizing Middlebox

To enable the transparent proxy and the DNS proxy, add the following to your torrc.

VirtualAddrNetwork 10.192.0.0/10
AutomapHostsOnResolve 1
TransPort 9040
TransListenAddress 127.0.0.1
TransListenAddress 192.168.1.1
DNSPort 53
DNSListenAddress 127.0.0.1
DNSListenAddress 192.168.1.1

Configure your system's DNS resolver to use Tor's DNSPort on the loopback interface by modifying /etc/resolv.conf.

nameserver 127.0.0.1

Use the iptables ruleset below as an example.

#!/bin/sh

# destinations you don't want routed through Tor
NON_TOR="192.168.1.0/24 192.168.0.0/24"

# the UID Tor runs as
TOR_UID="109"

# Tor's TransPort
TRANS_PORT="9040"

# your internal interface
INT_IF="eth0"

iptables -F
iptables -t nat -F

iptables -t nat -A OUTPUT -o lo -j RETURN
iptables -t nat -A OUTPUT -m owner --uid-owner $TOR_UID -j RETURN
for NET in $NON_TOR; do
  iptables -t nat -A OUTPUT -d $NET -j RETURN
  iptables -t nat -A PREROUTING -i $INT_IF -d $NET -j RETURN
done
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 $TRANS_PORT

iptables -t nat -A PREROUTING -i $INT_IF -p udp --dport 53 -j REDIRECT --to-ports 53
iptables -t nat -A PREROUTING -i $INT_IF -p tcp --syn -j REDIRECT --to-ports $TRANS_PORT

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
for NET in $NON_TOR 127.0.0.0/8; do
  iptables -A OUTPUT -d $NET -j ACCEPT
done
iptables -A OUTPUT -m owner --uid-owner $TOR_UID -j ACCEPT
iptables -A OUTPUT -j REJECT


3. BSD (pf)

Required software:

Assumptions:

3.1. Local Redirection Through Tor

To enable the transparent proxy and DNS proxy, add the following to your torrc.

AutomapHostsOnResolve 1
TransPort 9040
DNSPort 53

Configure your system's DNS resolver to use Tor's DNSPort on the loopback interface by modifying /etc/resolv.conf.

lookup file bind
nameserver 127.0.0.1

As root, create a second loopback interface.

ifconfig lo1 create up 127.0.0.2

Use the pf ruleset below as an example.

# destinations you don't want routed through Tor
non_tor = "{ 192.168.1.0/24 192.168.0.0/24 }"

# Tor's TransPort
trans_port = "9040"

scrub in

rdr pass on lo1 inet proto tcp all -> 127.0.0.1 port $trans_port
rdr pass on lo1 inet proto udp to port domain -> 127.0.0.1 port domain

block return out

pass out quick on lo0 route-to lo1 inet proto tcp to 127.192.0.0/10 flags S/SA modulate state
pass quick on { lo0 lo1 } keep state

pass out quick inet to $non_tor keep state
pass out quick inet proto tcp user _tor flags S/SA modulate state
pass out quick route-to lo1 inet proto udp to port domain keep state
pass out route-to lo1 inet proto tcp all flags S/SA modulate state


3.2. Anonymizing Middlebox

To enable the transparent proxy and the DNS proxy, add the following to your torrc.

VirtualAddrNetwork 10.192.0.0/10
AutomapHostsOnResolve 1
TransPort 9040
DNSPort 53

Use the pf ruleset below as an example.

# your internal interface
int_if = "fxp0"

# Tor's TransPort
trans_port = "9040"

set skip on lo

scrub in

rdr pass on $int_if inet proto tcp to !($int_if) -> 127.0.0.1 port $trans_port
rdr pass on $int_if inet proto udp to port domain -> 127.0.0.1 port domain


3.3. Local Redirection and Anonymizing Middlebox

To enable the transparent proxy and the DNS proxy, add the following to your torrc.

VirtualAddrNetwork 10.192.0.0/10
AutomapHostsOnResolve 1
TransPort 9040
DNSPort 53

Configure your system's DNS resolver to use Tor's DNSPort on the loopback interface by modifying /etc/resolv.conf.

lookup file bind
nameserver 127.0.0.1

As root, create a second loopback interface.

ifconfig lo1 create up 127.0.0.2

Use the pf ruleset below as an example.

# your internal interface
int_if = "fxp0"

# destinations you don't want routed through Tor
non_tor = "{ 192.168.1.0/24 192.168.0.0/24 }"

# Tor's TransPort
trans_port = "9040"

scrub in

rdr pass on { lo1 $int_if } inet proto tcp to !($int_if) -> 127.0.0.1 port $trans_port
rdr pass on { lo1 $int_if } inet proto udp to port domain -> 127.0.0.1 port domain

block return out

pass quick on { lo0 lo1 } keep state

pass out quick inet to $non_tor keep state
pass out quick inet proto tcp user _tor flags S/SA modulate state
pass out quick route-to lo1 inet proto udp to port domain keep state
pass out route-to lo1 inet proto tcp all flags S/SA modulate state

noreply: TheOnionRouter/TransparentProxy (last edited 2008-03-27 22:44:06 by cypherpunks)