在我去指责某人之前,我需要确认一些事情……好吧,我不想说。
问题:
我们允许用户上传图像并将其嵌入我们网站上的文本中。过去,我们也允许用户热链接到我们的图像,但由于服务器负载,我们不幸不得不停止这一点。
当前的“解决方案”:
程序员解决“连接过多”问题的方法是将接收和处理图像请求的文件(image_request.php)重命名为image_request2.php,并将显然
<?php
header("HTTP/1.1 500 Internal Server Error") ;
?>
,这导致所有 src 属性指向原始 image_request.php 的图像被破坏,并且在这种情况下发送的代码也是错误的。
建议的解决方案:
我觉得更优雅的解决方案是:
在.htaccess中
- 如果请求是针对image_request.php
- 检查引用者
- 如果引用者不是我们的网站,则发送适当的标头
- 如果引用者是我们的网站,请继续到 image_request.php 并处理图像请求
我想知道的是:
与简单地为每个请求返回 500 到 image_request.php 相比:
更多负载会是多少如果我们使用我提出的上述替代解决方案,会产生什么费用?
有更好的方法吗?
我们主要担心的是该网站能否正常运行。我不愿意同意破坏所有内部链接的图像是解决此问题的最佳/唯一方法。我拒绝告诉我们的用户,由于我们更改了某些内容,他们现在必须手动更改之前上传的所有内容中的嵌入代码。
I need to confirm something before I go accuse someone of ... well I'd rather not say.
The problem:
We allow users to upload images and embed them within text on our site. In the past we allowed users to hotlink to our images as well, but due to server load we unfortunately had to stop this.
Current "solution":
The method the programmer used to solve our "too many connections" issue was to rename the file that receives and processes image requests (image_request.php) to image_request2.php, and replace the contents of the original with
<?php
header("HTTP/1.1 500 Internal Server Error") ;
?>
Obviously this has caused all images with their src attribute pointing to the original image_request.php to be broken, and is also the wrong code to be sending in this case.
Proposed solution:
I feel a more elegant solution would be:
In .htaccess
- If the request is for image_request.php
- Check referrer
- If referrer is not our site, send the appropriate header
- If referrer is our site, proceed to image_request.php and process image request
What I would like to know is:
Compared to simply returning a 500 for each request to image_request.php:
How much more load would be incurred if we were to use my proposed alternative solution outlined above?
Is there a better way to do this?
Our main concern is that the site stays up. I am not willing to agree that breaking all internally linked images is the best / only way to solve this. I refuse to tell our users that because of something WE changed they must now manually change the embed code in all their previously uploaded content.
发布评论
评论(4)
好的,那么您可以使用 Apache 的 mod_rewrite 功能来防止热链接:
http://www.cyberciti.biz/faq/apache-mod_rewrite-hot-linking-images-leeching-howto/
Ok, then you can use mod_rewrite capability of Apache to prevent hot-linking:
http://www.cyberciti.biz/faq/apache-mod_rewrite-hot-linking-images-leeching-howto/
使用 ModRwrite 可能会比运行 PHP 脚本带来更少的负载。我认为你的解决方案会更轻松。
确保仅当引用标头不为空时才在步骤 3 中阻止访问。某些浏览器和防火墙完全阻止引用标头,您不想阻止它们。
Using ModRwrite will probably give you less load than running a PHP script. I think your solution would be lighter.
Make sure that you only block access in step 3 if the referer header is not empty. Some browsers and firewalls block the referer header completely and you wouldn't want to block those.
我假设您将图像路径与图像 ID 一起存储在数据库中,对吧?
然后查询数据库中的图像路径并为其提供图像 ID。
我建议你在服务器上安装 MemCached 并缓存用户请求。用 PHP 很容易做到。之后,您将看到服务器负载并决定是否应该完全停止这种热链接。
I assume you store image paths in database with ids of images, right?
And then you query database for image path giving it image id.
I suggest you install MemCached to the server and do caching of user requests. It's easy to do in PHP. After that you will see server load and decide if you should stop this hotlinking thing at all.
您增加的负载等于 PHP 中字符串比较的负载 (zilch)。
混淆解决方案甚至不能从一开始就解决问题,因为它不能阻止未来热链接的发生。如果您检查引用标头,请绝对确保所有主要主流浏览器都会按照您的预期设置标头。它是一个可选标头,对于 HTML 文档中嵌入的图像,不同浏览器的行为可能有所不同。
您可能为所有请求启用了会话(无论它们是否经过身份验证)——作为备份计划,您还可以将会话 cookie 名称重命名为一些模糊的名称(编辑:只要 cookie 存在,这里的模糊性实际上并不重要)仅为您的主机设置(确实如此))并检查 image_request.php 中是否设置了该名称的 cookie(没有 cookie 设置将表明这是对您站点的第一个请求)。仅将其用作后备或冗余检查。这比检查推荐人更糟糕。
如果您通过 markdown 或其他方式动态生成 IMG HTML,则可以使用私钥哈希策略,并在查询字符串上附加一个短暂的过期时间。完全气密,但对于你正在做的事情来说似乎有点太过分了。
此外,没有“适当的标头”可以向客户端谎报资源的可用性;)只需发送 404。
Your increased load is equal to that of a string comparison in PHP (zilch).
The obfuscation solution doesn't even solve the problem to begin with, as it doesn't stop future hotlinking from happening. If you do check the referrer header, make absolutely certain that all major mainstream browsers will set the header as you expect. It's an optional header, and the behavior might vary from browser to browser for images embedded in an HTML document.
You likely have sessions enabled for all requests (whether they're authenticated or not) -- as a backup plan, you can also rename your session cookie name to something obscure (edit: obscurity here actually doesn't matter as long as the cookie is set for your host only (and it is)) and check that a cookie by that name is set in image_request.php (no cookie set would indicate that it's a first-request to your site). Only use that as a fallback or redundancy check. It's worse than checking the referrer.
If you were generating the IMG HTML on the fly from markdown or something else, you could use a private key hash strategy with a short-live expire time attached to the query string. Completely air tight, but it seems way over the top for what you're doing.
Also, there is no "appropriate header" for lying to a client about the availability of a resource ;) Just send a 404.