是否可以阻止 Tor 用户?(https://www.torproject.org/)
由于我运行的网站的性质,我应该尽我所能停止多个帐户并阻止某些位置。Tor 比代理更糟糕——简直是一场噩梦……
是否可以阻止 Tor 用户?(https://www.torproject.org/)
由于我运行的网站的性质,我应该尽我所能停止多个帐户并阻止某些位置。Tor 比代理更糟糕——简直是一场噩梦……
Tor 比其他开放代理更容易被阻止,因为出口 IP 地址列表是已知的并已发布。在https://www.torproject.org/docs/faq-abuse.html.en#Bans阅读答案,如果您仍想阻止用户访问您的网站,您可以使用https://www.torproject.org/ projects/tordnsel.html.en或批量退出列表导出工具。
如果您使用批量退出列表导出工具,请确保经常获取新列表并过期旧块,因为 IP 地址列表发生更改。
阻止 Tor 是错误的,因为(ab)用户和 IP 地址不相同。通过阻止 Tor,您还将阻止配置了保守退出策略的合法用户和无害的受限 Tor 退出节点。
例如,如果您担心对 SSH(端口 22)的攻击,那么仅阻止 Tor 对提高安全性无济于事。您真正需要的是动态同步黑名单,例如http://denyhosts.sourceforge.net/,它可以跟踪违规者,无论他们是否与 Tor 有关联。
Denyhosts 将自动阻止允许 Tor 访问端口 22 的 Tor 出口节点,而无需拒绝匿名用户和 Tor 出口节点的运营商的访问,这些用户和运营商从不让违规者攻击您的 SSH 服务。
Tor 项目实际上在这里提供了自己的列表:
在 .NET 中,这是可能且简单的。我已经在我的网站上实现了它。
假设您的站点的外部 IP 地址为 192.168.0.5 以进行论证。发帖时的真实 TOR IP 地址:95.215.44.97
Imports System.Net
Imports System.Net.Sockets
Imports System.Web
Private Function IsTorExitNode(sIP As String) As Boolean
' Reverse your IP (97.44.215.95) then pass to the string, I have just created it as one for this example
Try
Dim strTor As String = "97.44.215.95.80.5.0.168.192.ip-port.exitlist.torproject.org"
Dim host As IPHostEntry = Dns.GetHostEntry(strTor)
If host.AddressList.Length = 0 Then
Return False
Else
If host.AddressList(0).ToString() = "127.0.0.2" Then
Return True
Else
Return False
End If
End If
Catch ex As SocketException
Return False
End Try
End Function
反向 IP 地址:97.44.215.95
端口:80
反向 IP 地址:(您的外部站点 IP 地址)
如果地址是 TorExitNode,它将返回 127.0.0.2。
在您的 Global.asax 文件中,您可以使用 Application_Start 检查 IP 地址是否返回 true,然后将它们重定向到您的站点之外:
If IsTorExitNode("97.44.215.95") = True Then Response.Redirect("http://www.google.co.uk")
现在,一旦他们访问您的网站,他们就会被重定向离开它。
TOR 有一个IP 地址列表,但显然它们一直在变化,因此使用我的功能将是最好的方法,因为它始终是实时的。
您可以使用TorDNSEL 服务实时查询特定 IP 地址是否是 Tor 出口节点。您通过特殊格式的 DNS 请求查询服务。
下面是一些执行查找的示例 PHP 代码:
function isTorExitNode() {
$serverPort = $_SERVER['SERVER_PORT'];
$remoteAddr = reverseIp(getClientIp());
$serverAddr = reverseIp($_SERVER['SERVER_ADDR']);
$placeholders = '%s.%s.%s.ip-port.exitlist.torproject.org';
$name = sprintf($placeholders, $remoteAddr, $serverPort, $serverAddr);
return ( gethostbyname($name) === '127.0.0.2' );
}
function getClientIp() {
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
}
return $_SERVER['REMOTE_ADDR'];
}
function reverseIp($ip) {
$ipParts = explode('.', $ip);
return $ipParts[3] . '.' . $ipParts[2] . '.' .
$ipParts[1] . '.' . $ipParts[0];
}
if (!isTorExitNode()) {
// Do nothing
} else {
Die("Sorry, You cannot use TOR network!!!");
}
重要笔记:
此示例仅支持 IPv4 地址,不支持 IPv6。
获得响应可能需要几秒钟的时间,因此请小心在您的网站渲染中引入延迟。
事实上,最好的应用程序防御是它的代码和安全性,而不是防火墙阻止列表。如果拥有真正的真实用户对您来说至关重要 - 您必须使用双因素身份验证。如今,阻止列表完全没用。
这里(参见https://github.com/RD17/DeTor)是一个简单的 REST API,用于确定请求是否来自 TOR 网络。
请求是:
curl -X GET http://detor.ambar.cloud/
。
回应是:
{
"sourceIp": "104.200.20.46",
"destIp": "89.207.89.82",
"destPort": "8080",
"found": true
}
作为奖励,您可以向您的网站添加徽章以检测用户是否来自 TOR:
<img src="http://detor.ambar.cloud/badge" />
(这是为一个 PHP 特定问题编写的,该问题随后被删除并在此处作为副本链接)。
免责声明:考虑在此处的最佳答案中提出的阻止所有 Tor 用户的影响。只考虑阻止功能,如注册、支付、评论等,而不是一揽子阻止一切。
--
这里有两个纯 PHP 解决方案。第一个下载并缓存一个 Tor 节点列表,并将访问者 IP 与列表进行比较。第二个使用Tor DNS 退出列表项目来确定访问者是否通过 DNS 查找使用 Tor。
使用下面的一组函数,我们可以通过检查一个被下载并缓存 10 分钟的动态退出列表来确定一个 IP 是否属于 Tor 网络。请随意使用此列表,但请尽可能缓存 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://www2.openinternet.io/tor/tor-exit-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;
}
}
DNS 退出检查更加健壮,因为它考虑了中继的退出策略,并查看客户端连接到的服务器上的 IP 和端口,如果允许此类退出流量,它将返回匹配项。潜在的失败是,如果 DNS 项目暂时停止,DNS 请求可能会在超时之前挂起,从而减慢速度。
对于此示例,我将使用我编写和维护的库中的一个类TorUtils。
首先,您需要使用 Composer 安装它,composer require dapphp/torutils
并将标准vendor/autoloader.php
代码包含在您的应用程序中。
检查代码:$isTor = false;
try {
// check for Tor using the remote (client IP)
if (TorDNSEL::isTor($_SERVER['REMOTE_ADDR'])) {
// do something special for Tor users
} else {
// not using Tor, educate them! :-D
}
} catch (\Exception $ex) {
// This would likely be a timeout, or possibly a malformed DNS response
error_log("Tor DNSEL query failed: " . $ex->getMessage());
}
if ($isTor) {
// blocking action
}
如果您的应用程序使用 PHP 会话,我强烈建议将“isTorUser”响应缓存到会话中(连同源 IP),并且仅在最初或当 IP 更改时(例如$_SERVER['REMOTE_ADDR'] != $_SESSION['last_remote_addr']
)运行检查,以免执行许多重复的查找。尽管他们试图非常高效,但为同一个 IP 一遍又一遍地做是一种浪费。
我发现每半小时更新一次的所有 Tor 节点列表:https ://www.dan.me.uk/tornodes
这应该包括用于连接和浏览 Tor 的出口、入口和桥接节点。
使用此 Perl 脚本从下载的网页收集 IP 地址:
perl -lne 'print $& if /(\d+\.){3}\d+/' downloadedwebpage.html > listofips.out
它会给你一个 IP 地址列表,每行一个。我试图找到不用 Perl 脚本就能做到这一点的东西,但经过几个小时的搜索,我找不到一个。
我希望这有帮助。
我也在同一个网站上找到了一些很好的信息: https ://www.dan.me.uk/dnsbl
检测 Tor 流量相当容易。执行此操作的主要方法是监视Tor 出口节点列表并将 IP 与列表进行比较。
我最近需要做这样的事情,并构建了一个小型 Ruby gem 来保持出口节点列表的最新状态,并提供一种检测出口节点的简单方法。我还编写了一个小型可执行文件,可用于检测退出节点。
gem 是开源的,可以在这里找到:tor-guard
安装 gem 很简单:
$ gem install tor-guard
在您自己的 Ruby 代码中使用该库可以如下完成:
require 'tor-guard'
if TorGuard.exit_node?('108.56.199.13')
puts "Yep, it's an exit node!"
end
该可执行文件也易于使用:
$ tg 108.56.199.13 && echo "Yep, it's an exit node"
由于 TorDNSEL 在 2020 年 4 月 [1] 已弃用并被新系统取代,因此该线程中的大多数答案都已过时。
经过一番争论,我想出了这个使用新检查器的代码。它的作用是反转 ip 八位字节并为新检查器创建一个 URL,然后执行 DNS 请求并检查第一个答案是否具有“127.0.0.2”IP。如果是这种情况,则认为用户来自 Tor,否则返回 false。
function IsTorExitPoint(){
$dns_record = dns_get_record(ReverseIPOctets($_SERVER['REMOTE_ADDR']).".dnsel.torproject.org.");
if ($dns_record && $dns_record[0] && $dns_record[0]["ip"] == "127.0.0.2") {
return true;
} else {
return false;
}
}
function ReverseIPOctets($inputip){
$ipoc = explode(".",$inputip);
return $ipoc[3].".".$ipoc[2].".".$ipoc[1].".".$ipoc[0];
}
[1] https://lists.torproject.org/pipermail/tor-project/2020-March/002759.html
PD:自从我发布 stackoverflow 的答案以来已经有一段时间了,所以请多多包涵,并尽可能帮助我改进。
这是可能的,因为 tor 项目发布了退出代理列表。
退出代理列表可以直接从项目中下载,地址为https://check.torproject.org/exit-addresses,以空格分隔的文本形式。
我编写了一个 python 脚本来为所有拒绝来自它们的所有数据包的退出节点添加 iptables 规则。你可以在这里找到 github 上的脚本:https ://github.com/vab/torblock
如果 Tor 项目决定停止发布退出节点列表,则可能会阻止它们。只需要编写代码来连接到 Tor 网络并发现出口节点。
是的,事实上这里有一个脚本可以为您的所有 Windows 机器执行此操作。像上面提到的其他人一样,它就像阻塞所有出口节点一样简单,但这需要一些工作。
我已经整理了每小时更新的 tor 节点和 tor 出口节点列表。请参考https://github.com/SecOps-Institute/Tor-IP-Addresses
您可以每小时执行一次 git pull 并获取最新列表。
无论出于何种原因,我无法在此处找到另一个答案,截至目前(20 Shevat 5781(来自 Creation))具有此特定链接,所以这里是:
https://check.torproject.org/torbulkexitlist
我通过下载 Tor 获得它,然后打开一个查找我的 IP 地址网站,然后导航到该 IP 地址(它恰好是http://195.176.3.20/,如果你导航到它,你应该也可以找到列表),并导航到它....