Blocking TOR IPs on router with OpenWRT system

March 26, 2022    Blog Post

Tor, short for The Onion Router, is free and open-source software for enabling anonymous communication


Why to block Tor IPs ?

Some people say that Tor network is used by people which don’t have access to uncensured infromations in the country where they are. This is true, but … Tor network is used as well by individuals who are using Tor’s ability of anonymous communications and trying to probe/hack your server(s) or other network devices.

To block or not to block ? it’s Your decision.


How this works ?

Tor publish list of IPs on which one all Tor exit nodes are running under url https://check.torproject.org/torbulkexitlist. We will use this data to create ipset setname which will contains all IPs published on url. Next we will use iptables to create rule which will DROP all trafic listed in ipset defined setname. List of Tor’s exit nodes IPs published by Tor project is dynamic, so we will run ipset setname creation daily via cron.

This solution will not only works on router with installed OpenWRT software. It will work on any router or Linux/Unix system with running IPtables and installed ipset utility. I choose to run it on my router as it is my main network device which connects me to Internet.


Installation

Prerequirements

To make this script working on OpenWrt, it requires packages wget, ipset, libustream-openssl to be installed:

# opkg update
# opkg install libustream-openssl ipset wget

On other Linux/Unix systems, general requirements is to have installed software packages iptables,ipset and wget.

To clone repository with ipsetbuild source code you will need git, but you don’t have to install it on your router. Clone repository https://github.com/monsoft/ipsetbuild.git on your local workstation and only copy nesesery file to the router.

To clone repository run command:

# git clone https://github.com/monsoft/ipsetbuild.git

Script installation

Create /opt/ipsetbuild directory in your filesystem (in filesystem of my OperWrt /opt directory doesn’t exist ) by running command:

# mkdir -p /opt/ipsetbuild

Copy listbuilder.sh script to /opt/ipsetbuild and setup execution bit on it:

# cp listbuilder.sh /opt/ipsetbuild
# chmod u+x listbuilder.sh

Setup

Add ipset and rule configuration to IPtables firewall by adding below lines to end of /etc/config/firewall file right bofore config include line:

 config ipset                  
         option name 'tornodes' 
         option match 'src_ip'
         option storage 'hash'
         option enabled '1'              


 config rule                  
         option src 'wan'      
         option ipset 'tornodes'
         option dest '*'
         option target 'DROP'
         option name 'DENY-from-TOR-Network'
         list proto 'all'

and restart firewall service:

# /etc/init.d/firewall reload

After configuring firewall, run script manually for 1st time:

# /opt/ipsetbuild/listbuilder.sh

It should pull data from Tor webiste and place them into tornodes setname. You can check it by running:

# ipset list tornodes|wc -l
1248

Crontab

I choose to run script once a day at 1AM but You can run it at different time and withh different frequency. Run crontab -e and add line to crontab setup:

0 1 * * * /opt/ipsetbuild/listbuilder.sh

Does it work ?

After some time, you can login to your router and check IPtable rule conuter so see if rule blocked any traffic:

# iptables -L -n -v |grep DENY-from-TOR-Network
   62  3564 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set tornodes src /* !fw3: DENY-from-TOR-Network */

Update

Since OpenWrt version 22.03 there is not iptables and ipset as both has been replaced by nftables. I uploaded another version of ipsetbuild to GitHub repository called listbuilder_nft.sh.

Installation and configuration is quite similar to iptables version.

Script installation

Follow instruction for iptables version but with using file listbuilder_nft.sh instead of listbuilder.sh.

Setup

Add below lines to /etc/config/firewall :

config ipset                  
        option name 'tornodes' 
        option match 'src_net'
        option storage 'hash'
        option enabled '1'              
        option loadfile '/etc/tornodes.ips'


config rule                  
        option src 'wan'      
        option ipset 'tornodes'
        option dest '*'
        option target 'DROP'
        option name 'DENY-from-TOR-Network'
        list proto 'all'

Create file /etc/tornodes.ips by running touch command:

touch /etc/tornodes.ips

Reload firewall service on OpenWrt:

/etc/init.d/firewall reload

This setup creates nftables set named tornodes with list of IPs stored in file /etc/tornodes.ips.

1st Run

Run script manually to populate /etc/tornodes.ips file and inject its contento into tornodes.

/opt/ipsetbuild/listbuilder_nft.sh

You can check if IPs has been added to set by running command:

nft list set inet fw4 tornodes

and count entries:

nft list set inet fw4 tornodes|grep -o ','|wc -l

Crontab

Setup crontab to run at 1AM each day:

0 1 * * * /opt/ipsetbuild/listbuilder_nft.sh