Предотвращать хотлинкинг файлов Amazon S3?

Я хотел бы разрешить кому-либо воспроизводить видео, расположенное в моем s3 на моем сайте, в качестве src в src <video> но не позволять людям использовать его как src на своем сайте или напрямую воспроизводить видео, набрав URL-адрес в панель браузера.

Я не хочу, чтобы люди это делали:

введите описание изображения здесь

и я не хочу, чтобы следующий HTML-код появлялся на http: // your -site.com, но только на http: // my -site.com:

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

Я видел некоторые ссылки SO на этом, но я хотел поговорить в коде, так как я не смог заставить эти решения работать для меня.

Вот моя политика ведра, которая в настоящее время НЕ работает:

 { "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 в тестовый файл на свой локальный хост и, конечно же, могу получить доступ к видео, набрав http://localhost/test.html . Почему моя ведровая политика не предотвращает это? (Я бы хотел, чтобы он работал только с http://my-site.com/test.html )
  2. Чтобы пользователи не вводили URL-адрес s3 в панель браузера, я думал, что мне нужно отдельное решение из политики ведра, поскольку мне не ясно, из документации AWS, как предотвратить прямой доступ через браузер. Я думал о хэшировании URL-адреса, чтобы было сложно догадаться. Возможно, существуют способы использования политики ковша AWS или других решений?

Чтобы быть более ясным, мои файлы хранятся на s3, но они доставляются CloudFront от Amazon. Так что мой CloudFront url src в настоящее время является media.my-site.com/my-video.mp4. CNAME – media.my-site.com.

Учитывая, что 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.

Это решение, надеюсь, будет достаточно хорошим, чтобы препятствовать людям злоупотреблять вашим сайтом, но отнюдь не идеально.

Вместо прямой привязки к вашим S3-файлам вы можете использовать PHP в качестве прокси-сервера, чтобы конечный пользователь никогда не видел фактический URL-адрес S3, и вы можете легче проверить референта? Для этого вам, вероятно, понадобится какая-то база данных, поэтому вы можете связать 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 или что угодно, и вы можете просто поместить ссылки, например, http://my-site.com/file/get_file.php?id=120381 в свой HTML.

Чтобы сделать еще один шаг, вы можете использовать файл .htaccess для маршрутизации запросов, таких как http://my-site.com/file/120381.mp4 на http://my-site.com/file/get_file.php?id=120381 .

Я не уверен, как хорошо это сработает, и код PHP, который я предоставил, был просто примером, чтобы помочь передать мою идею; это не идеальный код, поэтому, пожалуйста, не уменьшайте меня только ради этого.