TOR Transparent Proxy
This article will go through the steps necessary to set up a gateway machine that transparently routes traffic through the TOR network. The goal is to have a subnet that will have all TCP traffic routed through TOR which should prevent any leaking of information by the TOR browser (for instance, due to a browser vulnerability).
Prerequisites
You must have a machine that has at least two network interfaces (one for the external network, one for the TOR network). This guide was created against a clean installation of CentOS 7.1 x86_64.
The two networks will have the following configuration:
| Description | Interface | Addresses |
|---|---|---|
| External Network Interface (to internet) | eno16777728 | 10.1.3.39/22 |
| Internal Network Interface (to internal TOR subnet) | eno33554952 | 192.168.192.1/24, 192.168.192.2/24 |
This host will be the gateway for the internal TOR subnet and will have two addresses. One as the gateway IP address, and another for an internal website. The internal website is optional, though I'm adding it since this project will be used as part of a public WiFi network which requires registration.
Installation
Install the TOR package. You can find the TOR repository at https://deb.torproject.org/torproject.org/.
For CentOS 7, the packages are at https://deb.torproject.org/torproject.org/rpm/el/7/x86_64/.
Disable SELinux.
Configuration
Create the dnsmasq.conf file:
listen-address=192.168.192.1
port=53
strict-order
no-resolv
# Remote DNS server (this should go to TOR's DNS service)
# This is set to 1.1.1.1 which is routed by IPTables to TOR's service.
# DNSMasq does not allow you to set this to an internal IP address.
server=1.1.1.1
interface=eno33554952
address=/torified.wifi/192.168.192.1
dhcp-script=/scripts/dnsmasq_dhcp
dhcp-range=192.168.192.20,192.168.192.250,2h
dhcp-option=1,255.255.255.0
dhcp-option=6,192.168.192.1
dhcp-option=3,192.168.192.1
# This is the external (non TOR) network interface.
no-dhcp-interface=eno16777728
domain=torified.wifi
log-queries
log-dhcp
Create the torrc file containing: (/etc/tor/torrc)
Log notice file /var/log/tor/notices.log
DataDirectory /var/lib/tor
VirtualAddrNetwork 10.192.0.0/10
TransPort 9040
TransListenAddress 192.168.192.1
DNSPort 5353
DNSListenAddress 192.168.192.1
AutomapHostsOnResolve 1
Create the firewall configuration script (firewall.sh):
#!/bin/sh
IPT=/usr/sbin/iptables
TOR_UID=998
TOR_NET=192.168.192.0/24
TOR_IF=eno33554952
OUT_IF=eno16777728
$IPT -F
$IPT -t nat -F
# Connections cannot be forwarded from one network to another.
$IPT -A FORWARD -i $TOR_IF -j REJECT
# Accept HTTP traffic.
$IPT -t nat -A PREROUTING -i $TOR_IF -p tcp -d 192.168.192.1 --dport 80 -j ACCEPT
$IPT -t nat -A PREROUTING -i $TOR_IF -p tcp -d 192.168.192.1 --dport 443 -j ACCEPT
# Accept DNS traffic (handled by dnsmasq which goes to 1.1.1.1)
$IPT -t nat -A PREROUTING -i $TOR_IF -p udp -d 192.168.192.1 --dport 53 -j ACCEPT
# DNSMasq will send DNS queries to 1.1.1.1 which will be routed to the TOR DNS service
$IPT -t nat -A OUTPUT -p udp -d 1.1.1.1 --dport 53 -j DNAT --to-destination 192.168.192.1:5353
# Client chain. Append clients who should have access to this chain.
$IPT -t nat -X tor_clients
$IPT -t nat -N tor_clients
$IPT -t nat -A PREROUTING -i $TOR_IF -j tor_clients
# Allow all clients to connect.
# $IPT -t nat -A tor_clients -i $TOR_IF -p udp --dport 53 -j REDIRECT --to-ports 53
# $IPT -t nat -A tor_clients -i $TOR_IF -p tcp --syn -j REDIRECT --to-ports 9040
# Allow a specific client to connect.
$IPT -t nat -A tor_clients -i $TOR_IF -p udp -s 192.168.192.128 --dport 53 -j REDIRECT --to-ports 53
$IPT -t nat -A tor_clients -i $TOR_IF -p tcp -s 192.168.192.128 --syn -j REDIRECT --to-ports 9040
# Allow the 1.1.1.1 DNS redirection (UDP to the TOR server IP)
# Allow DNS to TOR 5353 service. Allow DNS from this host to the subnet.
$IPT -A OUTPUT -p udp --dport 5353 -j ACCEPT
$IPT -A OUTPUT -p udp -s 192.168.192.1 -d 192.168.192.1/24 -j ACCEPT
# Allow this talking to internal network
$IPT -A OUTPUT -p tcp -s 10.1.3.39 -d 10.1.1.0/22 -j ACCEPT
# Allow TOR
$IPT -A OUTPUT -m owner --uid-owner $TOR_UID -j ACCEPT
$IPT -A OUTPUT -j LOG --log-prefix "drop: " --log-level 4
$IPT -A OUTPUT -j REJECT