防止亚马逊S3文件的热链接?

时间:2012-07-17 12:35:45

标签: php amazon-s3 amazon-web-services referrer hotlinking

我想允许任何人在我的网站上播放位于我的s3中的视频作为src标记上的<video>,但允许人们使用它在其网站src直接通过在浏览器栏中输入网址来播放视频。

希望人们这样做:

enter image description here

我不希望以下HTML显示在http:// 您的 -site.com上,但仅限于http:// my -site.com :

<html>
    <video src="https://s3.amazonaws.com/my-bucket/my-video.mp4"></video>
</html>

我已经看到了一些SO links,但我想用代码说话,因为我无法让这些解决方案适合我。

这是我的存储桶政策,目前正在运作:

{
"Version": "2008-10-17",
"Statement": [
    {
        "Sid": "AllowPublicRead",
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::my-bucket/*",
        "Condition": {
            "StringLike": {
                "aws:Referer": [
                    "https://my-site.com/*"
                ]
            }
        }
    }
  }

两个问题:

  1. 要测试我的存储分区策略,我将上面的HTML放在我的localhost上的测试文件中,并确定我可以通过键入http://localhost/test.html来访问该视频。为什么我的桶政策不能阻止这种情况? (我只希望它可以从http://my-site.com/test.html
  2. 开始工作
  3. 为了防止人们将s3 URL输入浏览器栏,我想我需要一个独立的存储桶策略解决方案,因为我从AWS文档中不清楚如何阻止通过浏览器直接访问。我想要散列网址让人难以猜测。也许有些方法可以使用AWS桶策略或其他解决方案吗?
  4. 为了更清楚,我的文件存储在s3上,但它们由亚马逊的CloudFront提供。所以我的CloudFront url src目前是media.my-site.com/my-video.mp4。 CNAME是media.my-site.com。

2 个答案:

答案 0 :(得分:6)

鉴于CloudFront目前不允许您直接限制访问(据我所知),我会做类似的事情:

<video src="/media.php?v=my-video.mp4"></video>

然后您的media.php文件如下:

if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != 'my-site.com')
{
  header('HTTP/1.1 503 Hot Linking Not Permitted');
  // display some message / image / video
  exit;
}

# this base url changes from time to time
$url = 'http://cdn.my-site.com';

header("Location: $url/{$_GET['v']}");

为了使其不太明显,您可能需要设置重写以将/media/my-video.mp4路由到文件中。这样,它看起来不像是一个中间的PHP脚本。

究竟如何进行引荐来源检查取决于您想要的安全级别。有些人禁用推荐人,所以你可能想要允许空推荐人。或者您甚至可以检查会话变量或cookie是否存在等等。

当然,最终用户将能够嗅出真实的URL。这就是您可能希望不时更改CNAME的原因。

此解决方案有望足以阻止人们滥用您的网站,但绝不是完美的。

答案 1 :(得分:4)

您可以使用PHP作为代理,而不是直接链接到您的S3文件,以便最终用户永远不会看到实际的S3 URL,您可以更轻松地验证引用者吗?您可能需要某种类型的数据库,因此您可以将ID链接到S3文件。例如(无视安全措施):

<?php
$file = $_GET['id'];
$referer = $_SERVER['HTTP_REFERER'];

if($referer === 'http://my-site.com/test.html'){
    $s3 = //Query your database of S3 files with the ID provided to get the S3 URL
    header(mime_content_type($s3));
    include($s3);
}
?>

这可以保存为get_file.php或您想要的任何内容,您可以在HTML中添加http://my-site.com/file/get_file.php?id=120381之类的链接。

要更进一步,您可以使用.htaccess文件将http://my-site.com/file/120381.mp4之类的请求路由到http://my-site.com/file/get_file.php?id=120381

我不确定这会有多好用,我提供的PHP代码只是一个例子来帮助传达我的想法;它不是不是完美的代码所以请不要仅仅为此向我投票。