Table of Contents

Shortnote

Tor, i2p and other Darknet relays can be set-up by chaining various proxies. A good ground to do so is that there are no proxy servers that do not have any defects or can offer the necessary flexibility or supporting features to use Tor:

This leads to the generic topology documented in many places on the Internet:

In fact, the Vidalia bundle offered by the Tor website follows the same generic set-up out of the box.

Topology

This setup assumes the following:

Configuration Steps

  1. Proxy auto-discovery has to be set-up to hint to a proxy on port 8118.
  2. Tor has to be set-up to listen on 127.0.0.1 and port 9050 for SOCKS connections and on 127.0.0.2 and port 53 for DNS queries.
  3. i2p is preconfigured to listen on 127.0.0.1 and port 4444.
  4. Bind will be configured to forward requests for the .onion domain to Tor on 127.0.0.2 and port 53.
  5. Polipo will be configured to filter and cache requests from privoxy.
  6. Privoxy will be configured to:
    • forward clearnet requests to polipo on 127.0.0.1 port 8123.
    • forward .onion domain requests to Tor via SOCKS on 127.0.0.1 and port 9050.
    • forward .i2p requests to i2p on 127.0.0.1 and port 4444.

1. Proxy Auto-Discovery

Proxy-autodiscovery requires a webserver, configured to serve a wpad.dat file. DHCPd can hint to the wpad.dat file using the following configuration directives:

option proxy-auto-discovery code 252 = text;
option proxy-auto-discovery "http://192.168.0.1/wpad.dat";

where http://192.168.0.1/wpad.dat is the URL to a local webserver serving wpad.dat. The wpad.dat file can have the following contents:

wpad.dat
function FindProxyForURL(url, host) { 
    if (isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
        isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
        isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
        isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0") ||
        shExpMatch(host, "localhost") ||
        shExpMatch(host, "*.local") ||
        isPlainHostName(host))
        return "DIRECT";
    return "PROXY 192.168.0.1:8118"; 
}

For Windows clients, a proxy.pac should be set-up using the same contents of the wpad.dat and served by the web-server.

For more details, please see the proxy auto-discovery page.

2. Tor

The relevant configuration lines in Tor, are the following:

SocksPort 9050
SocksListenAddress 127.0.0.1
SocksPolicy accept 127.0.0.1
VirtualAddrNetwork 10.192.0.0/10
AutomapHostsOnResolve 1
DNSPort 53
DNSListenAddress 127.0.0.2
AutomapHostsSuffixes .exit,.onion 

and further tweaking can be done using the speed tweaks on the FUSS page.

3. i2p

Debian-based distributions can fetch the i2p package from the official i2p Debian page. Otherwise, i2p can be downloaded from the official download page. Squeeze users will have to download the source-code from the second address and compile it:

cd /usr/src/
wget -c http://mirror.i2p2.de/i2psource_0.9.6.tar.bz2
tar -jxvf i2psource_0.9.6.tar.bz2
cd i2p-0.9.6/
ant pkg
java -jar i2pinstall.exe -console

ant can be installed on Debian using aptitude install ant. Assuming that the installation directory was chosen as /opt/i2p, some changes to /opt/i2p/i2prouter have to be made.

First, create a group and user for i2p:

groupadd i2p
useradd -g i2p -d /opt/i2p i2p

and change permissions on /opt/i2p, with:

chown -R i2p:i2p /opt/i2p

Next, edit /opt/i2p/i2prouter and set:

RUN_AS_USER="i2p"

Finally, start i2p with:

/opt/i2p/i2prouter start

and install i2p with:

/opt/i2p/i2prouter install

which will create a link from /etc/init.d/i2p to i2prouter so that i2p boots when the system starts up.

For a monit script see the i2p monit page.

4. Bind

Bind will need to forward .onion requests to Tor's DNS resolver. This can be accomplished by adding a forwarder zone to named.conf.local:

zone "onion" {
        type forward;
        forwarders { 127.0.0.2; };
        forward only;
};

This will make any queries for any .onion domains go to 127.0.0.2 and port 53 where Tor will be listening.

5. Polipo

The relevant lines in polipo's configuration are the following:

proxyAddress = "127.0.0.1"
proxyPort = 8123
allowedClients = 127.0.0.1

and polipo can be tweaked using the polipo speed tweak guide.

Additionally, for advertisement filtering the following directive can be added:

forbiddenUrl = about:blank

and the domain.txt file from our spam database should be downloaded and copied to /etc/polipo/forbidden.

6. Privoxy

The following line will make privoxy listen on 192.168.0.1 and port 8118:

listen-address  192.168.0.1:8118

this is where browsers are hinted to connect after fetching wpad.dat.

Privoxy can then forward requests via different routes using the following configuration directives:

## By default, everything goes through polipo
forward /       127.0.0.1:8123

## .onion domains go through Tor
forward-socks4a .onion  127.0.0.1:9050 .

## .i2p domains go through i2p
forward .i2p  127.0.0.1:4444 .

## Requests to thepiratebay.sx go through Tor
forward-socks4a .thepiratebay.sx        127.0.0.1:9050 .

## Requests to some local site are fetched directly without being proxied.
forward mysite.internal  .

Some header filtering is possible for privoxy using the censoring headers guide.

Intercepting SSL

Recent Squid versions have changed the way that SSL interception works. The necessary changes for the Squid 4.x configuration file are the following:

# Port for both HTTP and HTTP(s) interception.
http_port 0.0.0.0:8123 ssl-bump cert=/etc/squid/certs/proxy.pem generate-host-certificates=on dynamic_cert_mem_cache_size=8MB

# Bump all domains.
acl DiscoverSNIHost at_step SslBump1
ssl_bump peek DiscoverSNIHost
ssl_bump bump all


# Start the dynamic certificate generator.
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/ssl_db -M 8MB
sslcrtd_children 32 startup=5 idle=1
sslproxy_cert_error allow all

The main problem with intercepting SSL and dynamically generating certificates is that all bumped requests would have to be fetched directly. In fact, examining the Squid access log, all requests to SSL bumped websites would appear with HIER_DIRECT since the resources are fetched. To work around this issue, tun2socks can be used with packet mangling to transparently pass all HIER_DIRECT requests through Tor.

That being said, the following ACL can be added to the Squid configuration:

acl HTTPs port 443

and all packets matching HTTPs can be marked with the identifier 0x32:

tcp_outgoing_mark 0x32 HTTPs

Now, given that the tun2socks guide is followed, all resources that would have been retrieved directly will instead be retrieved through Tor.

Comments

Privoxy can act as an intercepting proxy, without the need for proxy-autodiscovery. Nevertheless, "Juliusz", makes a compelling argument that http sessions should not be intercepted at the packet level.

The following reasons are summarized and expanded upon:

"Juliusz" claims that the proxy auto-discovery features do not work well although OSX seems to honor the hints pretty well. In that sense, OSX's proxy configuration takes place on the OS network layer and is honored by every application, not just by browsers.

Although this setup may seem complicated, it is in fact quite flexible: