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:
- iptables 1.3.5 or later
- Tor 0.2.0.1-alpha or later
Assumptions:
- kernel IP forwarding is disabled
- you don't want traffic to 192.168.1.0/24 and 192.168.0.0/24 redirected through Tor
- your internal IP address is 192.168.1.1
your internal network interface is eth0
- Tor runs under UID 109
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.
# 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.
# 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.
# 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:
- Tor 0.2.0.1-alpha or later
Assumptions:
- kernel IP forwarding is disabled
- you don't want traffic to 192.168.1.0/24 and 192.168.0.0/24 redirected through Tor
your internal network interface is fxp0
- /dev/pf is readable (OpenBSD) or readable and writable (other BSDs) by Tor
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