Skip to content

Menu

  • Home
  • Sysadmin
  • Debian
  • Security
  • Docker

Blog by Constantin Herold | Theme by ThemeinProgress | Proudly powered by WordPress

Spaaacesysadmin & dev stuff

Using Ipsets to Block Tor Anonymity Network

February 23, 2021Debian, Security, Sysadmin Standard
Read time 2 minutes

Besides VPN and SOCKS5 proxies using the Tor anonymity network to scan servers and run brute force attacks is a common choice.

It is especially useful to circumvent rate limiting given that you have easy access to a set of over 1500 IP addresses.

So if you have your own rate limiting implementation make sure to not only limit by IP address but also by targeted user.

Disclaimer: This was just a fun evening project to learn iptable sets. Generally you would want to run a fully fledged firewall with a anonymity database or IPS.

Nevertheless it’s security through obscurity so keep that in mind.

Setup torblock.sh

Ipset uses hash tables to apply actions on a set of IP addresses.

You have to install ipset, dnsutils and wget.

apt install ipset dnsutils wget

The following script gets all tor exit nodes that can reach your server, adds them to a ipset and sets up a iptable rule to reject any incoming connections.

cat << 'EOF' > /root/scripts/torblock.sh
#!/bin/bash

PORTS=(22 80 443 143 993)

# Make sure we are running as root
if [[ "$EUID" -ne 0 ]]; then
  echo "Please run as root"
  exit 1
fi

if [[ ! -f /etc/debian_version ]]
  echo "Only Linux Debian has been tested"
  echo "For safety reasons the script will terminate now"
  exit 1
fi

WANIP=`dig +short myip.opendns.com @resolver1.opendns.com`

if [[ ! $WANIP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  echo "Error Wan IP resolving failed"
  exit 1
fi

# Cleaning up previous rules
echo "Cleaning up previous rules";
/sbin/iptables -D INPUT -j torblock >/dev/null 2>&1
/sbin/iptables -D FORWARD -j torblock >/dev/null 2>&1
/sbin/iptables -F torblock >/dev/null 2>&1
/sbin/iptables -X torblock >/dev/null 2>&1
/sbin/iptables -F torlognreject >/dev/null 2>&1
/sbin/iptables -X torlognreject >/dev/null 2>&1
/sbin/ipset -F torblockset >/dev/null 2>&1
/sbin/ipset -X torblockset >/dev/null 2>&1

echo "Setting up ipset hash table this can take some time..";

# Create a new set for individual IP addresses
/sbin/ipset -N torblockset iphash

UNEXPECTEDRESULT=false

# IPCOUNT TEMPFILE
TEMPFILE=/tmp/$$.tmp
echo 0 > $TEMPFILE

for PORT in "${PORTS[@]}"
do
    # Get a list of Tor exit nodes that can access $WANIP with $PORT, skip the comments and read IP line by line
    wget -q -O - "https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=$WANIP&port=$PORT" | sed '/^#/d' | while read IP
    do
        # Check if ipv4 is valid
        if [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            # Check if IP is NOT already in ipset
            if /sbin/ipset test torblockset "$IP" 2>&1 >/dev/null | grep -q "NOT"; then
                # Add each IP address to the new set
                /sbin/ipset -A torblockset "$IP"

                IPCOUNT=$(($(cat $TEMPFILE) + 1))
                echo $IPCOUNT > $TEMPFILE
            fi
        else
            UNEXPECTEDRESULT=true
        fi
    done
done

IPCOUNT=$(($(cat $TEMPFILE)))
unlink $TEMPFILE

if [ "$UNEXPECTEDRESULT" = false ] ; then
    # Filter our new set in iptables Prepended to other firewall rules (-I prepend)
    # Rejects are logged to /var/log/kern.log
    /sbin/iptables -N torblock
    /sbin/iptables -N torlognreject
    /sbin/iptables -I INPUT -j torblock
    /sbin/iptables -I FORWARD -j torblock
    /sbin/iptables -A torblock -m set --match-set torblockset src -j torlognreject
    /sbin/iptables -A torlognreject -m limit --limit 1/hour --limit-burst 1 -j LOG --log-prefix "IPTABLES_TORBLOCK_REJECTED: " --log-level 4
    /sbin/iptables -A torlognreject -j REJECT

    echo "Iptables TOR Network REJECT set up";
    echo "$IPCOUNT TOR Exit Nodes BLOCKED";
else
    echo "Error Unexpected TorBulkExitList result";
fi
EOF

chmod +x /root/scripts/torblock.sh

You should run it every 3 hours via cron.

0 */3 * * * /root/scripts/torblock.sh
@reboot sleep 60 && /root/scripts/torblock.sh

Write a Reply or Comment Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Create SWAP on ZFS ZVOL
  • Raspberry Pi Grafana Kiosk
  • Proxmox Grafana Dashboard
  • Proxmox Full Disk Encryption with SSH Remote Unlock
  • Login Mail Alert Using Rsyslog

Categories

  • Debian
  • Docker
  • Monitoring
  • Personal
  • Proxmox
  • Raspberry Pi
  • Security
  • Sysadmin