The I2P logo side-by-side with the Tor logo.

Enable both .onion and .i2p routing with Proxy Auto-Configuration

You can browse Tor hidden services (example.onion) and I2P services (example.i2p) by configuring your operating system or web browser’s proxy configuration to point to each of these services’ local proxy gateways. However, you’re limited to only using one at a time and are required to route all network traffic through the serivce’s proxy. Here is how you can use a Proxy Auto-Configuration (PAC) file to only route normal web traffic onto the clearnet while still having the option to browse .onion and .i2p services without having to switch your configuration around.

Please note that if your intention is to achieve the best possible privacy protections then this isn’t the article for you. The goal in this article is to enable devices to access content on the Tor and I2P network by their addresses in addition to using the internet as normal.

Your operating system and various software, including web browsers, may have a custom settings for configuring a proxy server. However, this isn’t enough when you only want to direct some traffic to a proxy service and especially when you want to direct specific traffic towards specific proxy servers.

This is where the Proxy Auto-Configuration (PAC) profile file comes in. PAC is a small JavaScript-like file that enables some limited scripting to evaluate a network request and direct the client to a specific network proxy. The file should be hosted on a web server so that it can be shared, and optionally auto-discovered, by all the devices on your network. The file can also be stored on the local computer or manually configured on each device.

Proxy auto-configuration file

The following PAC file forwards traffic going to .i2p to the I2P SOCKS proxy service (running on port 4447 by default), traffic to .onion to the Tor SOCKS proxy service (port 9050 by default), and any other traffic go directly (bypassing any proxies.)

function FindProxyForURL(url, host)
{
  if (shExpMatch(host, "*.i2p"))
  {
    return "SOCKS5 127.0.0.1:4447";
  }
  if (shExpMatch(host, "*.onion"))
  {
    return "SOCKS5 127.0.0.1:9050";
  }
  return "DIRECT";
}

function FindProxyForURLEx(url, host) {
  return FindProxyForURL(url, host);
}

The configuration language is a JavaScript dialect anno late 1990’s and modern PAC interpreters don’t understand modern JavaScript. There are plenty of limitations in today’s PAC parsers including trouble with parsing single-line conditionals that aren’t wrapped in curly brackets, and all expressions are expected to be terminated with semicolons.

Note that if you’re running Tor or I2P on a server on your network in addition to on your local devices, you can include multiple proxies for redundancy by separating them in the return statements with semicolons. The leftmost one is preferred and secondary ones will be attempted if the first doesn’t work.

Save this file to a server or your local computer, find the proxy configuration section of your favorite operating system or software, and provide a URL (http or file) to your PAC file. There are plenty of operating system and software specific restrictions and bugs with PAC so make sure that you test your deployment thoroughly.

Device auto-configuration

Assuming you’ve got a web server and a configurable DHCP server on your network (and who doesn’t); you can configure it to auto-configure devices on your network. Support varies quite a bit and you can only reliably assume Windows and macOS devices will auto-configure themselves.

The Web Proxy Auto-Discovery Protocol (WPAD) is quite simple to deploy: In your DHCP server configuration, enable DHCP option 252 and set it’s value to a URL pointing to your proxy auto-configuration file. By convention this file must be called “wpad.dat” and be located at the root of your server. E.g. “http://10.0.0.1:80/wpad.dat”. Note that the URL must contain the server port number even for the default HTTP port 80. DNS services may be unavailable without the proxy, so it’s common to provide the server address as an IP address.

Note that you’ll almost immediately run into a longstanding networking bug with PAC profiles on Android but you can work around them.

You can also optionally configure something called WPAD over DNS, but support for this in modern operating systems is practically non-existing.

Bonus points

If you control a configurable DNS server on your network, you’ll want to make sure it rejects any requests for .onion and .i2p domain names to prevent any DNS leakage. These special domains are handled by their respective proxy services and you’re not expected to look them up through DNS.