neunzehn83.de

Ein Mann, ein Blog, kein Plan.

TOR-Nutzer blocken, umleiten oder mit PHP unterscheiden

TOR Nutzer sperren

TOR-Nutzer können manchmal lästig werden. Glücklicherweise sind diese aber sehr leicht zu identifizieren, denn sämtliche IP-Adressen von TOR Exit-Nodes lassen sich über die Webseite des TOR-Projektes abfragen. Der Webservice filtert sogar nach denjenigen Nodes die einen bestimmten Server erreichen können. Deshalb kann hier die eigene Server-IP mit übergeben werden.

In meinem Fall bekommt man dann eine Liste mit ca. 1300 Tor Exit-IPs zurück. Das sind eine Menge IPs, gegen die man bei jedem Request abgleichen muss. Mit PHP und Datenbank schafft man sich somit schnell einen Performance-Killer. Mittels iptables Regel kann man diese Nutzer besser identifizieren und dann sperren oder umleiten.

Da 1300 Regeln aber selbst für iptables suboptimal sind, hashen wir alle IPs in einem ipset und prüfen Requests nur gegen das gehashte ipset.

Beispiel:

#!/bin/bash ipset -N tor iphash wget -q https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=123.123.123.123 -O -|sed '/^#/d' |while read IP do ipset -q -A tor $IP done

Da sich TOR Exit-Nodes oft ändern, sollte der Webservice regelmäßig automatisiert abgefragen werden.

Nun kann mit einer einzigen iptables Regel sehr einfach das komplette IP-Set gedropt werden. Wir wollen aber noch einen Schritt weiter gehen, und die TOR-User erst auf Webserver-Ebene unterscheiden.

Dazu legen wir zunächst einen eigenen vHost für TOR-Nutzer an, welcher nur auf einer internen IP lauscht. Der Server bekommt also beispielsweise die zusätzliche IP 10.0.0.1

IP hinzufügen

ip addr add 10.0.0.1/24 dev eth0

Apache vHost Beispiel:

<VirtualHost 10.0.0.1:80>
        ServerName 10.0.0.1
        DocumentRoot /var/www/tor

        ErrorLog ${APACHE_LOG_DIR}/tor-error.log
        CustomLog ${APACHE_LOG_DIR}/tor-access.log combined

        RewriteEngine On
        RewriteCond %{REQUEST_URI} !=/index.html
        RewriteRule ^ /index.html
</VirtualHost>

Dieser Beispiel-vHost leitet also alle Anfragen an die index.html in /var/www/tor weiter. Sämtliche Zugriffe werden in einer separaten Datei geloggt.

Alternativ kann der vHost aber in das selbe Verzeichnis zeigen wie der vHost für die "normalen" Besucher und TOR-Nutzer lediglich mittels "SetEnv TOR 1" flaggen, die so dann leicht auf PHP-Ebene unterschieden werden können! (SetEnv-Variablen sind via PHPs $_SERVER-Variable verfügbar).

Was wir jetzt noch benötigen, ist eine iptables Regel, die alle IPs aus dem TOR ipset von Port 80 auf die lokale Adresse 10.0.0.1:80 umleitet:

iptables -t nat -A PREROUTING -p tcp --dport 80 -m set --match-set tor src -j DNAT --to-destination 10.0.0.1:80

Geschrieben am Donnerstag, 04. Juni 2015 und abgelegt unter Linux.