[tor-dev] How to build a Router that will only allow Tor users

Lunar lunar at torproject.org
Tue Mar 15 17:43:11 UTC 2016

Martin Kepplinger:
> I try to configure OpenWRT in a way that it will only allow outgoing
> connections if it is Tor. Basically it is the opposite of "blacklisting
> exit relays on servers": "whitelisting (guard) relays for clients". It
> should *not* run Tor itself.

I actually implemented this while running Tor on the router. This
provides easy retrieval and validation of the consensus.

Before we go further, I think it's worthwhile to put a serious
disclaimer: such a setup will only prevent accidental leaks and will not
prevent targeted attacks. A determined attacker will be able to run a
relay long enough and with sufficient bandwidth to become a Guard. It
will then be trivial for them to recognize non-Tor packets coming at
one of its port.

I need to clean up my notes and turn them into a proper article for the
upcoming Tor Labs. Meanwhile, here's what I have written down already:

--- 8< ---

### First steps

1. Create a new Wi-Fi interface, mode Access Point.
2. Add Wi-Fi interface to new network named “filtered”.
3. Configure “filtered” to use a static address, and have a DHCP server.
4. Add “filtered” interface to new firewall zone named “filtered”.
5. Create a rule to allow input for DHCP (UDP port 67).

### Install tools

Get Tor!

    # opkg install tor

Is tor connected?

    # ls -l /var/lib/tor/cached-microdesc-consensus

Get `ipset`:

    # opkg install ipset

### /usr/sbin/refresh-tor-guard-set



    while true; do
            ipset -q create tor-guards     hash:ip,port
            ipset -q create tor-guards-new hash:ip,port

            awk '
    /^r / { cmd =     "ipset -q add tor-guards-new " $6 "," $7 "\n";
            cmd = cmd "ipset -q add tor-guards-new " $6 "," $8 }
    /^s / { if ($0 ~ /\<(Guard|Authority)\>/) { print cmd } }
    ' /var/lib/tor/cached-microdesc-consensus | sh

            ipset swap tor-guards-new tor-guards
            ipset destroy tor-guards-new

            sleep 3600

Needs to be set executable:

    # chmod +x /usr/sbin/refresh-tor-guards-set

### /etc/init.d/refresh-tor-guards-set


    #!/bin/sh /etc/rc.common



    start_service() {
            procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
            procd_set_param stderr 1 # same for stderr
            procd_set_param command /usr/sbin/refresh-tor-guard-set

Needs to be set executable:

    # chmod +x /etc/init.d/refresh-tor-guard-set


    # /etc/init.d/refresh-tor-guard-set enable
    # /etc/init.d/refresh-tor-guard-set start

### Extra firewall rule

config ipset
        option name             tor-guards
	option external		tor-guards
	option family		ipv4
        option storage          hash
        list match              'dest_ip'
        list match              'dest_port'

config rule
        option name             Allow-Tor-Traffic-on-filtered
        option src              filtered
        option dest             wan
	option family		ipv4
	option proto		tcp
        option ipset            tor-guards
        option target           ACCEPT

--- >8 ---

I think I made a few adjustments to the above scripts after more tests
since I took the above notes.

Hope that helps,
Lunar                                             <lunar at torproject.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.torproject.org/pipermail/tor-dev/attachments/20160315/2883be12/attachment.sig>

More information about the tor-dev mailing list