是否可以阻止Tor用户? (https://www.torproject.org/)
由于我运行的网站的性质,我应该尽我所能阻止多个帐户并阻止某些位置。 Tor比代理人更糟糕 - 一场噩梦......
由于退出IP地址列表已知并已发布,因此Tor比其他开放代理更容易阻止。阅读https://www.torproject.org/docs/faq-abuse.html.en#Bans的答案,如果您仍想阻止用户访问您的网站,您可以使用https://www.torproject.org/projects/tordnsel.html.en或批量退出列表导出工具。
如果您使用批量退出列表导出工具,请务必经常获取新的列表,并且因为IP地址列表更改而使旧块过期。
检测Tor流量相当容易。执行此操作的主要方法是监视Tor exit node list并将IP与列表进行比较。
我最近需要做这样的事情并构建一个小的Ruby 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"
由于tor项目发布退出代理列表,因此可能。
退出代理列表可以直接从https://check.torproject.org/exit-addresses的项目中以空格分隔的文本格式下载。
我编写了一个python脚本来为所有退出节点添加iptables规则,拒绝来自它们的所有数据包。你可以在这里找到github上的脚本:https://github.com/vab/torblock
如果Tor项目决定停止发布退出节点列表,则可以阻止它们。只需编写代码即可连接到tor网络并发现出口节点。
是的,事实上这是一个脚本,可以为所有的Windows机器执行此操作。像上面提到的其他人一样,它就像阻止所有退出节点一样简单,但这需要一些工作。
阻止Tor是错误的,因为(ab)用户和IP地址不相同。通过阻止Tor,您还将阻止使用保守退出策略配置的合法用户和无害的受限Tor退出节点。
例如,如果您担心对SSH(端口22)的攻击,那么仅阻止Tor将无助于提高安全性。你真正需要的是像http://denyhosts.sourceforge.net/这样的动态同步黑名单,跟踪违规者无视他们与Tor的关系。
Denyhosts将自动阻止Tor退出节点,这些节点允许Tor访问端口22,而不会不必拒绝访问Tor出口节点的匿名用户和操作员,这些节点永远不会让违规者攻击您的SSH服务。
The Tor Project实际上在这里提供了自己的列表:
在.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 addresses列表,但显然它们一直在变化所以使用我的函数将是最好的方式,因为它总是实时的。
您可以使用TorDNSEL service执行有关特定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!!!");
}
重要笔记:
事实上,最好的应用程序防御是它的代码和安全性,而不是防火墙阻止列表。如果拥有真正的真实用户是你必不可少的事情 - 你必须使用two-factor authentication。现在阻挡名单完全无用。
Here(请参阅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" />
我找到了每半个小时更新一次所有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
(这是针对PHP特定问题而编写的,后来被删除并在此处作为副本链接)。
免责声明:考虑阻止所有Tor用户的影响,如最佳答案所示。仅考虑阻止注册,付款,评论等功能,而不是对所有内容进行封锁。
--
这里有两个纯PHP解决方案。首先下载并缓存Tor节点列表,并将访问者IP与列表进行比较。第二个使用Tor DNS Exit List项目来确定访问者是否通过DNS查找使用Tor。
使用以下一组函数,我们可以通过检查下载并缓存10分钟的动态list来确定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://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;
}
}
DNS出口检查更加健壮,因为它考虑了中继的退出策略,并查看客户端连接到的服务器上的IP和端口,如果允许这样的退出流量,它将返回匹配。潜在的垮台是,如果DNS项目暂时关闭,DNS请求可能会在超时减速之前挂起。
对于这个例子,我将使用我编写和维护的库中的一个类,称为TorUtils。
首先,您需要使用composer require dapphp/torutils
在Composer中安装它,并在您的应用程序中包含标准的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反复做也是一种浪费。