Перейти к основному содержимому

Раздача видео из Yandex.Cloud Object Storage

· 3 мин. чтения

В прошлой статье я рассказал, как и зачем хранить видео в формате HLS. Теперь стоит уточнить пару нюансов как правильно настроить раздачу этого контента.

Ограничение доступа

Если залить файлы при помощи s3cmd в публично доступный бакет, то выложенное таким образом видео любой желающий сможет встроить на свой сайт. Если же это не то, чего вы хотели, и вы хотите ограничить эту возможность нам нужно

  • заливать файлы s3cmd указав ключ --acl-private. Без него s3cmd по умолчанию создает объекты с публичным ACL, который перебивает правила заданные политикой.
  • задать Политику доступа в бакет.

Сделать это можно выполнив следующую команду:

aws s3api put-bucket-policy --bucket $BUCKET --policy file://policy.json

Содержимое файла policy.json:

policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"CanonicalUser": "%IAM_USER_ID%"
},
"Action": "*",
"Resource": [
"arn:aws:s3:::%BUCKET%/*",
"arn:aws:s3:::%BUCKET%"
],
"Condition": {
"StringLike": {
"aws:referer": "https://console.cloud.yandex.*/folders/*/storage/bucket/%BUCKET%*"
}
}
},
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::%BUCKET%/*",
"arn:aws:s3:::%BUCKET%"
],
"Condition": {
"StringLike": {
"aws:referer": [
"http://%YOUR_SITE%*",
"https://%YOUR_SITE%*"
]
}
}
},
{
"Sid": "Explicit deny to ensure requests are allowed only from a specific domain.",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::%BUCKET%/*",
"arn:aws:s3:::%BUCKET%"
],
"Condition": {
"StringNotLike": {
"aws:referer": [
"http://%YOUR_SITE%*",
"https://%YOUR_SITE%*"
]
}
}
}
]
}

Замените %IAM_USER_ID%, %BUCKET% и %YOUR_SITE% на id вашего пользователя, имя бакета и сайт куда вы хотите выложить видео соответственно.

Разберем политики подробнее.

Первая разрешает доступ к объектам из веб-консоли облака. Без нее вы увидите что-то типа такого.

Вторая политика явно разрешает доступ к объектам если HTTP заголовок Referer начинается с адреса вашего сайта. Третья — запрещает, если он отличен от него.

Эти политики разрешают только чтение, если вы хотите потом дополнительно заливать объекты добавьте политику разрешающую это. Где %SERVICE_ACCOUNT_ID% — id аккаунта от имени которого выписаны ключи (access_key и secret_key), использующиеся для доступа в бакет.

{
"Sid": "Explicitly Allow Service account all actions",
"Effect": "Allow",
"Principal": {
"CanonicalUser": "`%SERVICE_ACCOUNT_ID%`"
},
"Action": "*",
"Resource": [
"arn:aws:s3:::`%BUCKET%`/*",
"arn:aws:s3:::`%BUCKET%`"
]
}

Соответственно, если кто-то попытается встроить видео напрямую из вашего бакета к себе на сайт, у него ничего не получится. Он вместо этого получит ошибку HTTP/1.1 403 Forbidden.

Disclaimer

Это не панацея. Этот способ не помешает скачать ваше видео, например при помощи curl передав правильный HTTP-заголовок.

Зато вам не придется платить за трафик с чужого сайта.

Если же вам кажется, что этих мер недостаточно и вы хотите еще усложнить жизнь тем, кто попытается скопировать видео себе, то вы можете использовать AES-128 шифрование ваших видео. В этом посте я подробно расскажу как это сделать.