.htaccess和阻止特定文件扩展名的困难
我有一个相当复杂的情况,我运行一个个人博客,每周五和周日,我会通过将音乐上传到一个文件夹中的音乐,在那里一个Flash mp3播放器可以访问它并为全世界播放它。最近,一些网站叫做Dizzler,它就像一个蜘蛛般的mp3文件(就像我在我的服务器上托管的那个),并且让人们通过他们自己的专有播放器播放它们。现在,我通常不会反对其他人为了自己的利益而使用我的服务器,但最近这一切都失控了。在12月的最后一周,他们设法在一首歌曲中增加了10万次点击,并且消耗了6GB的带宽。.htaccess和阻止特定文件扩展名的困难
在12月的最后一个星期,我编辑了我的.htaccess文件,以删除我的服务器上的mp3访问,而不会删除我的mp3(所以“拒绝所有”不是一个选项!),我用这个代码:
RewriteEngine on
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} !^(www\.)?mydomain.com [NC]
RewriteRule \.(mp3)$ - [NC,F]
Options -Indexes
它工作得很好但有一个例外 - 它打破了我的服务器上的每个WordPress安装。我的意思是,在索引页面之外,如果你点击了Wordpress中的一个条目,它将无法找到它。我的主机的解决方案是将“RewriteEngine on”添加到每个安装的每个.htaccess文件以及Web服务器根目录的根目录中。
这是一个很好的解决方案,所有的网页再次工作 - 但它不再阻止我的MP3文件在该文件夹中。
我该怎么办?
PS。为了澄清,上面的代码位于包含mp3的文件夹中的.htaccess文件中。希望有所帮助!
我发布这是另一个答案,而不是将此添加到我的其他帖子,因为它从不同的角度接近问题。在这里,我假设你所有的mp3都在同一个文件夹中。
你面临的问题是由于任何制作wordpress使用的媒体播放器的人都会马虎的编码。会发生什么是玩家在访问用户的机器上运行,并实际下载mp3并在本地播放。问题在于玩家根本没有提供任何有用的标题:useragent是您的浏览器,引用者是空白的等等。因此,完全不可能判断请求是否来自播放器,或者通过浏览器在音频搜索引擎中点击您的链接。真的,保护你的mp3免受索引的唯一方法是尽可能频繁地更改链接。
这正是该计划。简而言之,这里是我们要做的:
- 改变你的mp3的路径。这保持秘密。
- 创建一个脚本来代理的MP3歌曲,这就要求其改变每隔一小时
- 改变你所有的MP3播放器的用途使用MP3代理脚本,但有一个占位符键
- 创建一个脚本来有效的密钥代理您的网络服务器,它用实际密钥替换密钥占位符
- 使用
.htaccess
重写所有请求到您的服务器以使用网络服务器代理脚本。
这一切的结果是,你的用户体验是不会改变的,但如果一个爬虫抓取你的链接,他们只会是有效的,直到那一天的午夜,在这一点请求该URL将会导致一个蹩脚的消息(甚至是你问他们请不要下载你的东西的mp3)。
准备好了吗?好了,走吧!
步骤1:首先
第一件事,一定要重命名你的MP3文件夹!这将打破所有现有的链接(并且未能这样做将意味着所有已经被抓取的链接将保持有效)。其次,创建一个robots.txt
文件来阻止谷歌和其他搜索引擎索引你的mp3文件夹。
现在,创建在根目录下一个名为mp3serve.php
具有以下内容:
<?php
/* This script checks 'key', and if it's valid, serves the mp3
* A valid key is defined as the md5 of the current date in
* yyyy-mm-dd-hh format concatenated with the string
* "Hello there :)"
*
* The key can be anything so long as we are consistent in this
* and the viewer proxy thing we're going to make.
*/
// edit this variable to reflect your server
$music_folder = "/new/path/to/mp3s/";
// get inputs of 'file' and 'key'
// 'file' should be the filename of the mp3 WITHOUT the extension
$file = $_GET['file'];
$key = $_GET['key'];
// get todays date
$date = date("Y-m-d-H");
// calculate the valid key
$valid = md5($date+"Hello there :)");
if ($key == $valid)
{
// if the key is valid, get the song in the path:
print(file_get_contents("$music_folder/$file.mp3"));
}
else
{
// if the key is invalid, print an admonishing message:
print("Please don't try to download my songs, poopface.");
}
?>
这样做是需要一个MP3和某种关键的文件名,并提供该文件的内容如果密钥有效。请注意,此脚本:
- 使得在所有的
$file
点没有检查你指望它什么,比它试图以确保它仅会返回mp3文件的事实等。 - 不会为mp3文件返回有效的标题 - 它们会在浏览器中呈现为文本。这是很容易解决,但正确的头躲开我的那一刻......反正WordPress的MP3播放器不关心,所以这一切都很好:)
第2步:
现在对于稍微棘手的部分:我们必须动态地重写链接。最简单的方法是编写一个“本地代理”的东西,这实际上比听起来容易得多。我们要做的是编写一个脚本,获取您的页面将输出的内容,并更正mp3链接。在我的例子中,我们将编辑您的所有文章与他们的MP3,但如果你想要看起来这不是完全必要的。
首先,编辑你所有的文章与他们的MP3播放器。你可以自动执行此操作,但除非WP有“在所有文章中查找/替换”的功能,否则我会建议不要这样做,唯一的原因是你可能搞砸和毁坏你的文章。在任何情况下,对其进行编辑,并从/path/to/mp3s/<filename>.mp3
替换球员的MP3链接/mp3serve.php?file=<filename>&key=[{mp3_file_key}]
现在,在被称为proxyviewer.php
具有以下内容的根目录下创建另一个PHP脚本:
<?php
/*
* The purpose of this file is to act as a proxy in which we can dynamically
* rewrite the page contents. Specifically, we want to get the page that the
* user WOULD have seen, and replace all instances of our key placeholder
* with the actual correct key
*/
// get the requested path
$request = $_GET['req'];
// get what the source output WOULD have been
// NOTE: depending on your server's config, you -might- have to
// replace 'localhost' with your actual site-name. This will
// however increase page-load times. If localhost doesn't work
// ask your host how to access your site locally. To clarify,
// maybe show him this file.
$source = file_get_contents("http://localhost/$request");
// The reason we need to pass the request through apache (i.e. use the whole
// "http://localhost/" thing is because we need the PHP to be rendered, and
// I can't think of another way to do that using the original request uri
// calculate the correct key
$key = md5(date("Y-m-d-H")+"Hello there :)");
// replace all instances of "[{mp3_file_key}]" with the key
$output = str_replace("[{mp3_file_key}]",$key,$source);
//output the source
print($output);
?>
第3步:
现在为最后一部分:设置您的.htaccess文件从http://yoursite/some/request/here
所有请求重定向到http://yoursite/proxyviewer.php?req=some/request/here
不幸的是,我真的.htaccess文件不是很好,所以我不能给你确切的代码,但我想这不该”太难做了。
恭喜你,你完成了!
免责声明:
请注意,这里的代码是不是生产级代码。首先,我根本没有对它进行测试 - 尽管除非在某个地方出现错别字,他们应该都可以工作,但我建议您在与他们一起生活之前仔细检查它们。我一直非常小心,不让任何坏事发生,但它并没有进行任何严肃的检查,并且这是凌晨在这里,所以我可能忽略了一些事情。
FilesMatch是指令你需要:
<FilesMatch "\.mp3$">
Order Allow, Deny
Allow from localhost #Or the address of your player
Deny From All
</FilesMatch>
巨大的感谢Vinko Vrsalovic所有帮助,肯定帮我指出正确的方向,目前使用下面的代码:
SetEnvIfNoCase Referer www\.dizzler\.com bad_referer
SetEnvIfNoCase Referer ".*(dizzler|beemp3|skreemr).*" BlockedReferer
SetEnvIfNoCase REMOTE_ADDR ".*(220.181.38.82|202.108.23.172|66.232.150.219).*" BlockedAddress
# deny any matches from above and send a 403 denied
<FilesMatch "\.mp3$">
order deny,allow
deny from env=bad_referer
deny from env=BlockedReferer
deny from env=BlockedAddress
</FilesMatch>
今晚测试一下,如果它能工作,明天就会报告回来!
我想我的其他答案是更好的,但是这仍然是值得考虑的
通过一些问题的答案阅读,我被另一个想法来袭:让你的网页记录所有访问者的IP地址您的网站在过去的两个小时内(或者很多)。然后,创建一个运行2秒钟左右的作业,它会重写.htaccess文件,以便只允许在日志中访问这些IP地址的mp3文件。
这样一来,只有那些在过去两个小时内从您的网站提供过网页的用户才能访问您的音乐。这对绝大多数在音频搜索引擎中发现你的mp3的人来说都是错误的。
哇 - 谈论复杂。谢谢!但它可能需要一些时间来测试,因为它有点复杂,我仍然必须弄清楚如何改变我的MP3播放器以不同的方式访问文件。我将upvote这个,并希望最好 - 希望这一切都能正常工作,再次谢谢你! – JonLim 2010-01-12 13:23:38
坚持一秒钟......在你遇到所有麻烦之前,让我再测试一件事 - 我在一些评论中与Vinko Vrsalovic进行了讨论,现在似乎找不到,但可能有一个更简单的方法。再给我一两天来测试一下,我会回到你身边 – Mala 2010-01-12 17:11:00