Blocking Tor Exit Nodes by .htaccess with PHP

What is Tor?

Tor is a multi-layered anonymizing proxy, used by a lot of parties interested in privacy or avoiding government overreach (great firewall of China, for example).

It is also used by annoying spammers who don’t know how to configure a traditional VPN, so they rely on pre-configured browsers.

Candidates for this Method

If you run a forum, for example, where you’re not looking for Tor users to visit your site, you can simply deny them with .htaccess. This isn’t the most elegant solution, as a firewall would be ideal. But it is a quick win. This assumes you’re using Apache 2.4, PHP 7, and Ubuntu 16.04. It also requires root access or a user that can edit .htaccess of the site required and run PHP. You should also not have anything already in htaccess, as this will overwrite it. If you require htaccess later, this can be modified as needed.

Configure your VirtualHost

You will need to modify your virtual host (probably located in /etc/apache2/sites-available/——). Adding the code below will instruct Apache to process the htaccess files, make sure to modify the path as needed.

<Directory /path/to/site>
   Options Indexes FollowSymLinks
   AllowOverride All
   Require all granted

After completing the change, run this:

sudo apache2ctl configtest

If you see “Syntax OK” at the end, you did a good job. Restart Apache:

sudo service apache2 restart

Set up the PHP script by entering your path where it is bold below:

$nodeList = file_get_contents("");
$nodeList = str_replace("\r\n","\n",$nodeList);
$lines = explode("\n",$nodeList);

foreach ($lines as $v) {
 if (substr($v,0,11)=="ExitAddress") {
 $exitNode = explode(" ",$v);
 $exitNodes[] = $exitNode[1];

$file = fopen("/path/to/site/.htaccess","w");
fwrite($file,"# Any changes here will be overwritten. File managed by /automation/getTorNodes.php".PHP_EOL);
foreach($exitNodes as $v) {
 fwrite ($file,"Deny from $v".PHP_EOL);

I like to have this file in an automations folder. You can trigger it as often as you like, though I recommend not more than once a day. You can either manually trigger the php script, or add a cron job.

Bonus: If your firewall is a Ubiquiti Security Gateway:

You can SSH into it and modify /config/config.json and add this in. I haven’t tested persistence across re-provisioning. I’d suggest adding the group through the web UI first, finding the IP(s) you added in the JSON, and then adding them there.

 group {
 address-group 5a61631fe4b0d5a0bfa53416 {
 description customized-TorNodes




About Author

Robert Lerner

Leave a Reply

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