(Это было написано для конкретного вопроса PHP, который впоследствии был удален и связан здесь как дубликат).
Отказ от ответственности: рассмотрите влияние блокировки всех пользователей Tor, как описано в лучшем ответе здесь. Рассмотрим только блокирующие функции, такие как регистрация, оплата, комментарии и т. Д., А не общий блок для всего.
-
Вот два чистых решения PHP. Первый загружает и кэширует список узлов Tor и сравнивает IP-адрес посетителя со списком. Второй использует проект * * Список DNS Tor, чтобы определить, использует ли посетитель Tor через поиск DNS.
Метод # 1 (Проверка IP по списку ретрансляторов Tor):
Используя следующий набор функций, мы можем определить, принадлежит ли IP к сети Tor, проверив его по динамическому списку , который загружается и кэшируется в течение 10 минут. Не стесняйтесь использовать этот список, но, по возможности, сохраняйте его в кэше на 10 минут.
Там, где вы хотите применить проверку Tor, вы можете просто использовать:
$isTorUser = isTorUser($_SERVER['REMOTE_ADDR']);
if ($isTorUser) {
// blocking action
}
Вот код, который вы можете поместить в отдельный файл функций и включить, когда вы хотите выполнить проверку. Обратите внимание, что вы можете настроить некоторые из них, чтобы изменить путь к файлу кэша.
<?php
function isTorUser($ip)
{
$list = getTorExitList();
if (arrayBinarySearch($ip, $list) !== false) {
return true;
} else {
return false;
}
}
function getTorExitList()
{
$path = __DIR__ . '/tor-list.cache';
if ( file_exists($path) && time() - filemtime($path) < 600 ) {
$list = include $path;
if ($list && is_array($list)) {
return $list;
}
}
$data = file('https://openinternet.io/tor/tor-node-list.txt');
if (!$data) {
return array();
}
$list = array();
foreach($data as $line) {
$line = trim($line);
if ($line == '' || $line[0] == '#') continue;
list($nick, $ip) = explode("\t", $line);
$list[] = $ip;
}
sort($list);
file_put_contents($path, sprintf("<?php return %s;", var_export($list, true)));
return $list;
}
/**
* Perform binary search of a sorted array.
* Credit: http://php.net/manual/en/function.array-search.php#39115
*
* Tested by VigilanTor for accuracy and efficiency
*
* @param string $needle String to search for
* @param array $haystack Array to search within
* @return boolean|number false if not found, or index if found
*/
function arrayBinarySearch($needle, $haystack)
{
$high = count($haystack);
$low = 0;
while ($high - $low > 1){
$probe = ($high + $low) / 2;
if ($haystack[$probe] < $needle){
$low = $probe;
} else{
$high = $probe;
}
}
if ($high == count($haystack) || $haystack[$high] != $needle) {
return false;
} else {
return $high;
}
}
Метод № 2 (Проверка IP по проекту Tor Exit List Exit List):
Проверка выхода DNS немного более надежна в том смысле, что она учитывает политику выхода ретранслятора и смотрит, к какому IP-адресу и порту на вашем сервере подключен клиент, и если такой трафик выхода разрешен, он вернет совпадение. , Потенциальным недостатком является то, что, если проект DNS временно не работает, запросы DNS могут зависнуть, прежде чем истечет время ожидания, что замедлит работу.
В этом примере я буду использовать класс из библиотеки, которую я написал и поддерживаю, с именем TorUtils .
Во-первых, вам нужно установить его с помощью Composer, используя composer require dapphp/torutils
и включить в приложение стандартный код vendor/autoloader.php
.
код для проверки:
$ isTor = false;
try {
// check for Tor using the remote (client IP), server IP, and server Port (e.g. 80, 443).
$isTor = TorDNSEL::IpPort(
$_SERVER['SERVER_ADDR'],
$_SERVER['SERVER_PORT'],
$_SERVER['REMOTE_ADDR']
);
} catch (\Exception $ex) {
// This would likely be a timeout, or possibly a malformed DNS response
//echo $ex->getMessage() . "\n";
}
if ($isTor) {
// blocking action
}
Дополнительные соображения
Если ваше приложение использует сеансы PHP, я настоятельно рекомендую кэшировать ответ "isTorUser" в сеанс (вместе с исходным IP-адресом) и запускать проверку только изначально или при изменении IP-адреса (например, $_SERVER['REMOTE_ADDR'] != $_SESSION['last_remote_addr']
) как нет. выполнить многократный поиск. Даже при том, что они пытаются быть очень эффективными, это снова и снова тратить на один и тот же IP.