Running a Tor proxy on OpenBSD

There are few guides to running a Tor proxy on OpenBSD: of the few there are, most seem to be written by people who have never tested their proposed set up. AI simply regurgitates the same bad advice.

Here is the set up for a Tor Proxy which provides SOCKS and Transparent proxy capability, with a single NIC on the network. You can easily adapt this for use with two network cards. The basic approach is simple:

  1. Install

  2. Configure

  3. Test

Install Tor

pkg_add tor

I also install curl (for testing) and nyx to monitor circuits. pkg_add curl nyx

Configure as needed

The configuration file is at /etc/tor/torrc and is well documented, both internally and with man tor. I make the following configuration changes:

SOCKSPort "127.0.0.1:9050 IsolateClientAddr IsolateSocksAuth" # Default: Bind to localhost:9050 for local connections.
TransPort "127.0.0.1:9040 IsolateClientAddr" #
TransProxyType pf-divert
VirtualAddrNetwork "172.16.0.0/12"

DNSPort "127.0.0.1:53 IsolateClientAddr IsolateSocksAuth"
AutoMapHostsOnResolve 1

In the section on entry policies I set:

SOCKSPolicy accept 127.0.0.1
SOCKSPolicy accept 10.0.0.0/8

My local network is 10.0.0.0/8 - adjust these settings to suit your environment.

I also set Control Port 9051.

This is a very basic configuration. The tor daemon is listening on localport 127.0.0.1. Port 9050 provides a SOCKSPort: clients using this as a SOCKS proxy get different circuits depending on their IP address and any SOCKS authority. Port 9040 provides a TRANSPort: clients get different circuits depending on their IP address, and can use this as a transparent proxy. Port 53 provides the standard Tor DNS resolver using multiple resolvers accessed over Tor.

Configure pf

The simplest approach is to direct incoming SOCKS traffic to the SOCKS Port, DNS traffic to the DNS Port, and all other TCP to the TRANSPort. We will drop anything else and restrict OUTGOING traffic to the tor daemon.

In /etc/pf.conf:

ext_if    = "xnf0"
internal  = "10.0.0.0/8"
SOCKS_IP  = "127.0.0.1"
TRANS_IP  = "127.0.0.1"
DNS_IP    = "127.0.0.1"
SOCKSPort = 9050
TRANSPort = 9040
DNSPort         = 53

block all
set skip on lo0

pass out on $ext_if proto tcp from any user _tor

pass in quick on $ext_if proto tcp \
  from any to any port $SOCKSPort \
    rdr-to $SOCKS_IP port $SOCKSPort

pass in on $ext_if proto udp \
  from $internal to port $DNSPort \
  rdr-to $DNS_IP port $DNSPort

pass in on $ext_if proto tcp \
  from $internal to any \
    divert-to $TRANS_IP port $TRANSPort

Again, adjust this to suit your own requirements..

There are two significant settings for use of this machine as a transparent proxy - in the tor configuration we set TransProxyType pf-divert, and in the firewall settings we use divert-to for TCP Traffic: divert-to redirects packets without modifying the packets, unlike rdr-to, and the TRANSPort is configured to accept and process these packets. Every guide I have seen misses this point. If you want to ssh to test.rebex.net you simply do not want rdr-to to change the destination.

Change DNS resolution to use Tor

Edit /etc/resolv.conf to:

nameserver 127.0.0.1

Restart the firewall

pfctl -f /etc/pf.conf

Restart tor

rcctl enable tor
rcctl start tor

You should see tor(ok)

Test the circuit

A simple test is to run: netstat -a -f inet You should see listening ports as specified for the tor daemon.

Once you have the tor daemon running and have confirmed that it is listening properly, you can test it is working:

curl -x socks5h://127.0.0.1:9050 -s https://check.torproject.org |head -n20|grep Tor

This will test both DNS and SOCKS connectivity over Tor. If successful you will see "Congratulations. This browser is configured to use Tor." for each request.

Test from a client

From a client on the same network, you can test DNS, SOCKS and the transparent proxy, using a simple script:

#!/bin/sh
  curl -x socks5h://X.X.X.X:9050 https://check.torproject.org |grep Congratulations
  curl https://check.torproject.org |grep Congratulations

Replace X.X.X.X with the IP address of the Tor proxy.

If successful you will see "Congratulations. This browser is configured to use Tor." for both tests. Notice that you do not need to specify a proxy address for the second curl test. You do of course, have to route traffic to the Tor proxy.