Фото Raph Howald на Unsplash
🔥Вступ
В наш час відео-стрімінг став невід'ємною частиною того, як ми споживаємо контент. AWS надає потужні інструменти, такі як Elemental MediaConvert, S3 і CloudFront, для створення масштабованих, безпечних та оптимізованих робочих процесів для доставки відео високої якості. Однак інтеграція цих сервісів для безпечної доставки контенту вимагає глибшого розуміння того, як вони працюють разом.
У цьому блозі я проведу вас через процес безпечної доставки транскодованих відеофайлів і оптимізації доставки контенту за допомогою CloudFront. Основна увага буде зосереджена на налаштуванні розподілу CloudFront і конфігурації політики S3 для безпечного доступу. Якщо ви хочете побудувати повний робочий процес MediaConvert, ви можете ознайомитися з моїм репозиторієм на GitHub https://github.com/subratanath123/Video-Streaming-Micro-Service. Я докладно охоплю цей робочий процес в наступному блозі.
Чому не слід надавати доступ до відео безпосередньо з S3?
Хоча S3 є надійним і масштабованим рішенням для зберігання даних, воно не призначене для доставки з низькою затримкою або для обробки раптових пікових навантажень. Ось чому пряме надання доступу до відео з S3 не є ідеальним:
- Глобальна затримка: Бакети не оптимізовані для доставки з низькою затримкою по всьому світу. Користувачі, які знаходяться далеко від регіону бакету, можуть зіткнутися з повільним завантаженням відео.
- Піки трафіку: S3 не призначене для обробки раптових сплесків трафіку, що може призвести до обмеження пропускної здатності або зниження продуктивності.
- Ризики безпеки: Якщо зробити ваш бакет публічним для надання доступу до відео, це відкриває його для несанкціонованого доступу, що неприпустимо для захищеного контенту.
Щоб вирішити ці проблеми, рекомендованим рішенням є CloudFront, CDN (мережа доставки контенту) від AWS.
Огляд робочого процесу:
Крок 1: Безпечний доступ до контенту
Щоб запобігти несанкціонованому доступу до ваших відео, не робіть бакет публічним. Замість цього використовуйте підписані URL-адреси для надання тимчасового доступу до конкретних файлів.
Однак є проблема з .m3u8
маніфестами. Ці файли містять відносні шляхи до сегментів .ts
, які також потрібно підписати. Без підпису файлів .ts
відеопрогравачі не зможуть відтворити контент, навіть якщо URL маніфеста підписаний.
Крок 2: Використання CloudFront для оптимізованої доставки
Щоб забезпечити безпечну та низькозатратну доставку, налаштуйте розподіл CloudFront перед вашим S3 бакетом. Такий підхід має кілька переваг:
- Масштабованість: CloudFront ефективно обробляє великі навантаження.
- Низька затримка: Завдяки кешуванню контенту на точках присутності, відео доставляються швидше користувачам по всьому світу.
- Приватний контент: Ви можете подавати приватний контент, надаючи CloudFront дозвіл на доступ до вашого S3 бакету.
Ось як налаштувати ваш розподіл CloudFront для роботи з вашим S3 бакетом:
- Перейдіть до CloudFront у AWS і натисніть "Створити розподіл".
- Вкажіть домен походження: Вкажіть розподіл CloudFront на ваш S3 бакет як походження.
- Контроль доступу до походження (OAC): Коли ви подаєте приватний контент через CloudFront, важливо забезпечити безпеку походження (S3 бакету), щоб запобігти несанкціонованому доступу. Це досягається шляхом увімкнення Контролю доступу до походження (OAC) в CloudFront. OAC гарантує, що лише CloudFront може отримати доступ до вашого S3 бакету, а користувачі використовують підписані URL або підписані cookies для доступу до контенту.
У наведеній формі вам потрібно виконати кілька попередніх кроків для налаштування обмеження доступу для перегляду. Дотримуйтесь цих кроків. Потім ми повернемося до тієї ж форми, щоб завершити розподіл CloudFront.
Обмеження доступу для перегляду за допомогою підписаних URL-адрес CloudFront
Вам потрібно вибрати обмеження доступу для перегляду, щоб лише авторизовані користувачі могли отримати доступ до вашого контенту. Це досягається за допомогою підписаних URL-адрес CloudFront або підписаних cookies.
Ось як ви можете це налаштувати:
Генерація пари ключів RSA
Згенеруйте приватний ключ і збережіть його в файл з назвою private_key.pem
:
openssl genrsa -out private_key.pem 2048
Витягніть публічний ключ з приватного і збережіть його в файл з назвою public_key.pem
:
openssl rsa -pubout -in privatekey.pem -out publickey.pem
Для того, щоб активувати підписані URL-адреси або cookies, вам потрібно створити пару ключів RSA. Виконайте ці команди:
Завантаження публічного ключа в CloudFront
- Перейдіть в розділ Public Keys в налаштуваннях CloudFront у консолі AWS.
- Скопіюйте вміст файлу
public_key.pem
і вставте його в поле "Public Key". - Збережіть конфігурацію публічного ключа.
Створення групи ключів
- Перейдіть до розділу Key Groups в консолі CloudFront.
- Створіть нову групу ключів і виберіть публічний ключ, який ви щойно завантажили.
- Збережіть групу ключів, щоб завершити налаштування.
Завершивши ці кроки, ви забезпечите, щоб тільки авторизовані користувачі з дійсними підписаними URL-адресами або cookies могли отримати доступ до вашого контенту через CloudFront.
Тепер поверніться до форми створення розподілу CloudFront і налаштуйте цю конфігурацію для кешування:
Налаштування політики кешування
Використовуйте політику CachingOptimized
для CloudFront, яку AWS рекомендує для статичного контенту. Ця політика:
- Мінімізує значення, що включаються в ключ кешу (наприклад, виключає рядки запиту та cookies).
- Оптимізує ефективність кешування і забезпечує швидшу доставку.
Додавання політики для бакету, щоб дозволити доступ лише з розподілу CloudFront
- Додайте політику для бакету: Додайте політику для бакету, щоб дозволити CloudFront доступ до контенту.
{
"Version": "2012-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::video-output-bucket-final/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::231313333:distribution/EGFFKYGYGIGHH" //your cloudfront distribution arn
}
}
}
]
}
Крок 3: Реалізація підписаних URL-адрес для безпечного відтворення
Для безпечного надання відеофайлів реалізуйте підписані URL-адреси для маніфеста .m3u8
та його відповідних файлів .ts
.
Нижче наведено приклад сервісу Spring, який завантажує і обробляє маніфест файл, замінюючи відносні шляхи на підписані URL-адреси для файлів .ts
.
package com.video.streaming.streaming_service.service;
import com.amazonaws.services.cloudfront.CloudFrontUrlSigner;
import com.amazonaws.services.cloudfront.util.SignerUtils;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.S3Object;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Date;
import static com.video.streaming.streaming_service.constants.Constants.AWS_VIDEO_OUTPUT_BUCKET_NAME;
@Service
public class CloudFrontS3Service {
@Value("${aws.cloudfront.public.key.id}")
private String awsPublicKeyId;
@Value("${aws.cloudfront.distribution.domain}")
private String distributionDomain;
@Autowired
private AmazonS3 amazonS3;
public void downloadSignedM3U8File(String objectKey, HttpServletResponse response) {
Date expirationDate = new Date(System.currentTimeMillis() + 86400000); //налаштуйте відповідно до ваших потреб
response.setContentType("application/vnd.apple.mpegurl");
String basePath = objectKey.substring(0, objectKey.lastIndexOf("/") + 1);
try {
File cloudFrontPrivateKeyFile = generateCloudFrontPrivateKeyFile();
S3Object m3U8File = getAwsS3File(objectKey);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(m3U8File.getObjectContent()));
PrintWriter writer = response.getWriter()) {
String line;
while ((line = reader.readLine()) != null) {
if (line.endsWith(".ts")) {
String tsFile = line.trim();
String tsKey = basePath + tsFile;
String signedUrl = CloudFrontUrlSigner.getSignedURLWithCannedPolicy(
SignerUtils.Protocol.https,
distributionDomain,
cloudFrontPrivateKeyFile,
tsKey,
awsPublicKeyId,
expirationDate
);
writer.println(signedUrl);
} else {
writer.println(line);
}
}
}
} catch (IOException | InvalidKeySpecException exception) {
System.out.println(exception.getMessage());
}
}
private File generateCloudFrontPrivateKeyFile() {
return new File("/usr/local/aws/private_key.pem");
}
private S3Object getAwsS3File(String key) {
return amazonS3.getObject(AWS_VIDEO_OUTPUT_BUCKET_NAME, key); //AWS_VIDEO_OUTPUT_BUCKET_NAME - це ім’я бакету
}
}
X
Як це працює:
- Файл
.m3u8
завантажується з бакету S3. - Кожен сегмент
.ts
у маніфесті замінюється на підписану URL-адресу CloudFront. - Модифікований файл
.m3u8
надається користувачеві для безпечного відтворення відео.
Висновок
Поєднуючи AWS Elemental MediaConvert, S3 та CloudFront, ви можете побудувати безпечний та ефективний робочий процес потокового відео. Використання CloudFront для доставки контенту забезпечує низьку затримку, масштабованість та ефективність витрат. Додавання підписаних URL-адрес ще більше захищає ваш контент від несанкціонованого доступу.
Перекладено з: Secure and Optimized Video Streaming Using AWS Elemental MediaConvert, S3, and CloudFront