I've tried a lot of ways but all of them are not working for me, I guess they are outdated and things changed. Maybe someone can advise me the direction to dig out?
I am the author of a PHP library called TorUtils that provides a number of classes related to Tor and relays.
One of the classes it provides is TorDNSEL
example which gives you a simple interface to query the Tor DNS exit list to see if the remote IP is a Tor relay accessing your site.
The usage is simple (example updated 2022/02/04):
<?php
use Dapphp\TorUtils\TorDNSEL;
require_once 'src/TorDNSEL.php';
// Practical usage on a web server:
try {
if (TorDNSEL::isTor($_SERVER['SERVER_ADDR'])) {
// do something special for Tor users
} else {
// not using Tor, educate them! :-D
}
} catch (\Exception $ex) {
error_log("Tor DNSEL query failed: " . $ex->getMessage());
}
The TorDNSEL
script doesn't require any of the other classes and can be downloaded and used as a standalone script. It makes a DNS request, but builds it directly so you also don't need any DNS functions or libraries available to PHP.
Alternatively, I use the ControlClient
class to maintain very fresh exit lists. You can build your own lists using that (you'll need a Tor relay of your own to connect to, or you could use the Directory Authorities to build lists as well). Even easier, just periodically download and check the exit lists I export here. The list is updated every 10 minutes so please try not to download it more than once every 10 minutes or so.
Then save it to your site somewhere and check the client IP against the ones in the list.
You can download the source from GitHub or composer require dapphp/torutils
to install to an existing project.
Hope that helps, let me know if I can answer anything further.