# Amazon S3 및 CloudFront: 단계별 범위가 지정된 IAM 권한, 브라우저 CORS, CloudFront HTTPS 전달 및 업로드 확인 체크리스트를 사용하여 비공개 S3 버킷을 DRM-X 6.0에 연결합니다. 암호화된 동영상과 DRM 라이선스는 서로 다른 경로로 전달됩니다 CDN은 암호화된 동영상을 전달합니다. 백엔드가 접근 권한을 확인하고, DRM 라이선스 서비스가 호환 기기에서의 복호화를 승인합니다. - 01**스토리지 / CDN** 암호화된 미디어를 플레이어에 전달합니다. - 02**고객 백엔드** 시청 권한을 확인하고 DRM-X에 재생 승인을 요청합니다. - 03**DRM-X** 재생 승인 정보를 검증하고 DRM 라이선스 요청을 처리합니다. - 04**플레이어 + 기기** 기기의 DRM 시스템으로 라이선스를 받아 암호화된 미디어를 재생합니다. 귀하의 백엔드가 접근을 결정합니다. DRM-X는 서명 된 정책을 시행합니다. 암호화 된 미디어 및 DRM 라이센스는 별도의 배송 경로를 따릅니다. **비공개 버킷에서 암호화 미디어 공개 전송까지** S3 버킷을 만들고 DRM-X에 권한을 제한한 업로드 자격 증명을 제공합니다. 브라우저 CORS를 설정하고 CloudFront를 연결한 뒤 테스트 객체를 업로드하고 가져와 확인하세요. 원본 동영상과 개인 파일은 이 전송 버킷 밖에 보관합니다. ## 1. 연결 구조 이해하기[#](#architecture) DRM-X는 서명된 요청으로 S3에 직접 업로드합니다. 시청자는 CloudFront에서 HTTPS로 암호화된 미디어를 다운로드합니다. S3의 **Block all public access**는 활성화해 두세요. CloudFront에는 **Origin Access Control (OAC)**을 통해 제한된 읽기 권한을 부여합니다. CloudFront는 프로덕션에 사용할 수 있는 `https://….cloudfront.net` 호스트 이름을 제공합니다. 자체 도메인은 선택 사항입니다. 공개 전송을 사용하면 객체의 바이트를 가져올 수 있지만, 올바르게 패키징한 미디어의 복호화는 계속 DRM이 제어합니다. CORS는 접근 권한을 부여하는 기능이 아닙니다. 이 가이드는 일반적인 공개 CDN 전송을 사용합니다. 시청자용 서명 URL이나 쿠키는 별도 통합이 필요합니다. ## 2. S3 버킷 만들기[#](#create-bucket) ![AWS S3 생성 양식: General purpose, Global namespace 및 버킷 이름 예시.](https://docs.drm-x.com/assets/storage/s3-create.png)12**1:** General purpose를 선택하세요. **2:** 자신만의 고유한 이름을 입력하세요. 이는 제출되지 않은 예제가 포함된 실제 콘솔 형식입니다. 계정 헤더는 제외됩니다. - **Amazon S3 → General purpose buckets → Create bucket**를 엽니다. - 지역을 선택하고 `us-east-1`와 같은 코드를 기록하세요. **General purpose**를 선택하세요. 네임스페이스를 묻는 경우 이 연습에서는 **Global namespace**를 사용하세요. - 전역적으로 고유한 버킷 이름을 입력하세요. **Object Ownership → ACLs disabled (Bucket owner enforced)**를 유지하세요. - **Block all public access**를 선택하세요. 범위가 지정된 정책을 통해 CloudFront 액세스 권한을 부여합니다. - 이 가이드에서는 **Default encryption → Server-side encryption with Amazon S3 managed keys (SSE-S3)**를 유지하세요. 이 저장소 암호화는 DRM 패키징에 추가로 적용되며 DRM을 대신하지 않습니다. SSE-KMS를 사용하려면 업로더와 CloudFront에 추가 KMS 권한이 필요합니다. - 버킷을 검토하고 생성합니다. S3 정적 웹사이트 호스팅을 활성화하지 마세요. ## 3. 권한을 제한한 IAM 사용자와 액세스 키 만들기[#](#iam-credentials) - **IAM → Policies → Create policy → JSON**를 엽니다. 아래 정책을 붙여넣고 모든 위치에서 예제 버킷 이름을 바꿉니다. - 예제에서는 `protected/`만 허용합니다. 다른 기본 경로를 사용하는 경우 접두사 조건과 개체 ARN를 모두 업데이트하세요. 버킷 루트를 사용하려면 ListBucket 접두사 조건을 제거하고 객체에 `arn:aws:s3:::YOUR_BUCKET/*`를 사용하세요. - 정책을 저장합니다. **IAM → Users → Create user**를 열고, AWS Console 액세스 권한이 없는 전용 통합 사용자를 생성하고, 이 정책만 연결하세요. - 사용자의 **Security credentials → Access keys → Create access key**을 엽니다. 외부에서 실행되는 애플리케이션의 사용 사례를 선택하고(AWS) 프롬프트를 따릅니다. DRM-X의 경우 Access key ID 및 Secret access key를 안전하게 보관하세요. ``` { "Version": "2012-10-17", "Statement": [ { "Sid": "ListProtectedFolder", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::customer-drm-media-example", "Condition": { "StringLike": { "s3:prefix": [ "protected", "protected/", "protected/*" ] } } }, { "Sid": "BucketRegion", "Effect": "Allow", "Action": "s3:GetBucketLocation", "Resource": "arn:aws:s3:::customer-drm-media-example" }, { "Sid": "ManageProtectedObjects", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::customer-drm-media-example/protected/*" } ] } ``` 루트 키나 AdministratorAccess를 사용하지 마세요. 복사에는 GetObject 및 PutObject가 사용됩니다. 별도의 `s3:CopyObject` IAM 액션은 없습니다. 이름을 바꾸려면 DeleteObject도 필요합니다. 이 가이드는 DRM-X의 현재 액세스 키 형식을 따릅니다. 역할 ARN만으로는 키 쌍을 대체할 수 없습니다. ## 4. 브라우저 업로드를 위해 S3 CORS 구성[#](#bucket-cors) - S3 버킷 → **Permissions**을 엽니다. - **Cross-origin resource sharing (CORS) → Edit**으로 이동합니다. - 이것을 JSON에 붙여넣고, `https://www.example.com`를 플레이어를 삽입한 웹사이트로 바꾸세요. DRM-X Console 원점을 유지하세요. 기존 버킷에 다른 필수 규칙을 유지합니다. - **Save changes**를 선택하세요. Block Public Access 활성화 유지: CORS는 버킷을 공개하지 않습니다. ``` [ { "AllowedOrigins": [ "https://6.drm-x.com" ], "AllowedMethods": [ "PUT" ], "AllowedHeaders": [ "Content-Type", "x-amz-meta-drmx-sha256" ], "ExposeHeaders": [ "ETag" ], "MaxAgeSeconds": 3600 }, { "AllowedOrigins": [ "https://6.drm-x.com", "https://multi-drm.drm-x.com", "https://www.example.com" ], "AllowedMethods": [ "GET", "HEAD" ], "AllowedHeaders": [ "Range" ], "ExposeHeaders": [ "ETag", "Content-Length", "Content-Range", "Accept-Ranges" ], "MaxAgeSeconds": 3600 } ] ``` 업로드는 S3로 직접 이동하므로 PUT CORS는 S3에 속합니다. CloudFront까지 재생하려면 5단계의 CDN 구성도 필요합니다. ## 5. CloudFront HTTPS 전송 URL 만들기[#](#cloudfront) - **CloudFront → Distributions → Create distribution**를 엽니다. 표준 분포를 사용합니다. AWS에 온보딩 또는 가격 책정 계획 선택이 표시되면 리소스를 생성하기 전에 계정에 적합한 계획을 검토하고 선택하세요. - 웹사이트 엔드포인트가 아닌 버킷의 일반 **S3 REST origin**를 선택하세요. 이 가이드에서 사용되는 폴더 매핑의 경우 **Origin path를 비워두세요**. - **Origin access control settings (recommended)**를 선택합니다. **Sign requests (recommended)**를 사용하여 OAC를 생성하거나 선택합니다. - 뷰어 프로토콜 정책을 **Redirect HTTP to HTTPS** 또는 **HTTPS only**로 설정합니다. **GET, HEAD, OPTIONS**를 허용합니다. 업로드는 S3 엔드포인트를 사용하므로 CloudFront에는 PUT가 필요하지 않습니다. - CloudFront 배포를 만드세요. **S3 → Bucket → Permissions → Bucket policy → Edit**에서 CloudFront가 생성한 버킷 정책을 필요한 기존 정책과 병합합니다. 이 배포의 ARN에만 접근 권한을 부여하세요. 아래 예시는 읽기 범위를 `protected/`로 제한합니다. - **CloudFront → Policies → Response headers → Create response headers policy**를 엽니다. 아래 표에서 CORS 필드를 구성하세요. 이 정책을 배포의 미디어/기본 동작에 연결합니다. - 배포가 완료될 때까지 기다립니다. **Distribution domain name**를 복사하세요. 전송 Origin는 `https://YOUR_DISTRIBUTION.cloudfront.net`입니다. | Response headers 정책 분야 | 값 | | --- | --- | | Access-Control-Allow-Origin | 정확한 플레이어 출처에 DRM-X 테스트의 경우 `https://6.drm-x.com` 및 `https://multi-drm.drm-x.com`를 추가합니다. | | Access-Control-Allow-Methods | GET, HEAD, OPTIONS | | Access-Control-Allow-Headers | Range | | Access-Control-Expose-Headers | ETag, Content-Length, Content-Range, Accept-Ranges | | Access-Control-Allow-Credentials | 이 공용 암호화 미디어 워크플로에서는 비활성화됩니다. | | Access-Control-Max-Age | 3600 | | Origin override | 활성화되어 CloudFront가 시청자 방향 CORS을 일관되게 제어합니다. | OPTIONS 프리플라이트의 경우 관리형 **CORS-S3Origin** 원본 요청 정책을 첨부합니다. Origin, Access-Control-Request-Method, Access-Control-Request-Headers를 S3로 전달합니다. 처음에는 GET/HEAD만 캐시하고 OPTIONS 캐싱은 비활성화합니다. 나중에 OPTIONS를 캐시하는 경우 캐시 키에 이러한 헤더를 포함하고 다른 플레이어 출처를 테스트하세요. 헤더만 전달해도 캐시 키에 추가되지 않습니다. ``` { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowThisCloudFrontDistribution", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::customer-drm-media-example/protected/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EEXAMPLE123" } } } ] } ``` 예시 계정 ID, 배포 ID 및 버킷 이름을 바꿉니다. SourceArn는 방금 생성한 배포판을 식별해야 합니다. 헤더 변경 후 이전 응답이 캐시된 상태로 남아 있으면 영향을 받는 테스트/미디어 경로를 무효화합니다. ### 선택 사항: media.example.com 사용 - **US East (N. Virginia), us-east-1**에서 호스트 이름이 포함된 ACM 공개 인증서를 요청하고 DNS 검증을 완료하세요. - 배포판의 **Alternate domain names** 아래에 호스트 이름을 추가하고 인증서를 첨부하세요. - DNS 공급자에서 CNAME 또는 CloudFront 호스트 이름을 가리키는 지원되는 별칭을 만듭니다. DNS, 인증서 및 배포 배포를 기다립니다. - `https://media.example.com`를 전송 Origin로 사용하세요. CloudFront 도메인 및 인증서 설정 없이는 DNS CNAME만으로는 충분하지 않습니다. ## 6. Amazon S3를 DRM-X 6.0에 연결[#](#connect-drmx) [Cloud Storage → Connect storage](https://6.drm-x.com/console/cloud-storage)를 엽니다. **Amazon S3**를 선택하세요. | (주)에이치 | 입력할 내용 | | --- | --- | | Display name | Production S3처럼 알아보기 쉬운 이름입니다. | | Bucket name | 정확한 이름은 `s3://`이 없습니다. | | Region | 버킷의 정확한 AWS 지역 코드입니다. | | Protected-content base path | `protected`, IAM 및 버킷 정책과 일치합니다. | | Public URL prefix | `https://YOUR_DISTRIBUTION.cloudfront.net/protected` 또는 `https://media.example.com/protected`. | | Access key ID / Secret access key | 전용 IAM 사용자 키 쌍입니다. | 예제에서는 `protected`라는 폴더를 사용합니다. 버킷 이름은 자동으로 폴더가 아닙니다. 여기에 사용된 도메인-버킷 직접 매핑을 사용하면 동일한 스토리지 폴더를 공용 URL 접두사에 정확히 한 번 포함합니다. ``` Bucket: customer-drm-media-example Protected-content base path: protected Public URL prefix: https://media.example.com/protected File selected for upload: sample.encrypted.bin Object key in the bucket: protected/sample.encrypted.bin Preview URL: https://media.example.com/protected/sample.encrypted.bin ``` 버킷 루트를 사용하려면 기본 경로를 비워두고 공개 접두사로 전달 원본만 입력합니다. 의도적으로 폴더로 사용하지 않는 한 버킷 이름을 추가하지 마세요. 이 매핑에서는 CloudFront Origin path를 비워 둡니다. 원하는 경우 기본 업로드 대상을 선택한 다음 **Save and verify**를 선택하세요. S3 API 호스트 이름은 CloudFront 전송 URL이 아닙니다. ### CORS 및 일치하는 URL 필드를 생성합니다. 이 도구는 브라우저에서 실행됩니다. 공개 출처만 입력하세요. 액세스 키를 요구하지 않습니다. 플레이어 웹사이트 출처예를 바꿔보세요. 여러 개의 HTTPS 출처를 공백이나 쉼표로 구분하세요. 페이지 경로 없이 플레이어가 포함된 웹사이트를 사용하세요. DRM-X Console 및 Playback Lab는 자동으로 포함됩니다.공개 전송 Origin연결된 맞춤 도메인, 활성화한 r2.dev URL 또는 CloudFront Origin을 입력하세요. 여기에는 폴더 경로를 넣지 마세요.저장 폴더(옵션)구성 생성 CORS JSON 복사 ``` ``` Protected-content base path``Public URL prefix``객체 키 예시``완전한 URL 예시`` ## 7. 파일을 업로드하고 작동하는지 확인하세요.[#](#test-upload) - [Cloud Storage](https://6.drm-x.com/console/cloud-storage)를 열고 이 목적지를 선택한 다음 **Verify location**를 선택하세요. 성공은 DRM-X 서버가 버킷을 나열할 수 있음을 의미합니다. 쓰기 권한, 브라우저 CORS 또는 공개 전송을 설정하지 않습니다. - **Upload encrypted files**를 선택하고 기존 DRM-X 패키지에서 작은 암호화 세그먼트 하나를 선택합니다. 패키지가 없는 경우 아래 일회용 암호화 진단을 이용하세요. 원본 영상이나 개인 문서를 업로드하지 마세요. - 성공 메시지를 기다립니다. Cloud Storage에 파일 이름과 크기가 나타나는지 확인하세요. 공급자 콘솔의 `protected/` 아래에서 동일한 개체를 찾으세요. - **Preview URL**를 클릭하고 개인 브라우저 창에서 동일한 개체를 테스트하세요. AWS 또는 Cloudflare 로그인 없이 HTTP 200을 다운로드하거나 반환해야 합니다. 실제 객체를 테스트합니다. 객체 전달이 작동하는 경우에도 도메인의 루트가 403/404를 반환할 수 있습니다. - 플레이어 웹사이트에서 교차 Origin 전송을 확인하세요. 브라우저의 네트워크 패널에는 플레이어 페이지의 출처와 일치하는 `Access-Control-Allow-Origin`가 표시되어야 합니다. 직접 주소 표시줄 다운로드는 CORS를 테스트하지 않습니다. 아래 터미널 예제에서도 헤더를 확인합니다. - 완료되면 일회용 진단 개체만 제거하십시오. 그런 다음 [Desktop Packager 가이드](https://docs.drm-x.com/ko/packaging/desktop)에 따라 Package content에서 이 저장 대상을 선택한 다음 전체 암호화된 패키지를 업로드하세요. 파일을 수동으로 업로드하면 Published Content ID가 등록되지 않습니다. - [Universal Playback Lab](https://multi-drm.drm-x.com/ko/player) 및 자신의 플레이어 웹사이트에서 결과 Published 파일을 테스트합니다. 비디오, 오디오, 타임라인 탐색 및 필요한 장치를 확인하십시오. 성공적인 바이너리 다운로드는 DRM 재생의 증거가 아닙니다. 암호화된 샘플이 없나요? Windows에 일회용 테스트 파일을 만듭니다. 제어하는 ​​임시 폴더의 Windows PowerShell에서 이것을 실행하세요. 메모리에만 보관된 일회용 AES 키를 사용하여 짧은 비개인 메시지를 암호화합니다. 출력은 재생 가능한 미디어가 아닌 저장소 진단입니다. DRM 콘텐츠 키나 고객 데이터가 포함되어 있지 않습니다. ``` $samplePath = Join-Path (Get-Location) 'drmx-storage-check.encrypted.bin' if (Test-Path -LiteralPath $samplePath) { throw 'Choose a new folder; this test file already exists.' } $aes = [System.Security.Cryptography.Aes]::Create() try { $aes.GenerateKey() $aes.GenerateIV() $encryptor = $aes.CreateEncryptor() try { $bytes = [Text.Encoding]::UTF8.GetBytes('DRM-X disposable storage check') $encrypted = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length) [IO.File]::WriteAllBytes($samplePath, $encrypted) } finally { $encryptor.Dispose() } } finally { $aes.Dispose() } Get-Item -LiteralPath $samplePath | Select-Object Name, Length ``` `drmx-storage-check.encrypted.bin`을 업로드하고 크기와 Preview URL을 확인한 뒤, 해당 테스트 객체를 버킷에서 삭제하세요. ``` curl.exe -I -H "Origin: https://www.example.com" "https://media.example.com/protected/sample.encrypted.bin" ``` 두 URL을 모두 바꾸십시오. HTTP 200 및 플레이어 웹사이트와 일치하는 허용된 출처를 예상하세요. 범위 전달의 경우 `Range: bytes=0-15`가 포함된 GET 요청은 HTTP 206 및 유효한 Content-Range 헤더를 반환해야 합니다. 미디어 MIME 유형 유지: DASH 매니페스트는 application/dash+xml을 사용하고, HLS 재생 목록은 application/vnd.apple.mpegurl을 사용하며, 미디어 파일은 적절한 미디어 유형을 사용해야 합니다. ## 8. 결과 문제 해결[#](#troubleshooting) | 결과 | 액션 | | --- | --- | | Verify location은 성공하지만 브라우저 업로드가 실패함 | 브라우저 Console 및 네트워크 패널을 검사합니다. 정확한 Console 원점에서 PUT CORS 및 Content-Type를 허용합니다. 또한 연결을 확인하고 새로 서명된 URL을 다시 시도하세요. | | 업로드가 403을 반환합니다. | 객체 쓰기 권한, 버킷/폴더 범위, 엔드포인트, 지역, 요청 만료 및 시계를 확인하세요. 서명된 업로드 URL을 공유하지 마세요. | | 업로드가 성공했습니다. 공개 URL는 403을 반환합니다. | 공개 전송이 활성화되어 있고 도메인/배포판 배포가 완료되었는지 확인하세요. | | 공개 URL는 404를 반환합니다. | 전체 URL를 정확한 개체 키와 비교합니다. 누락되거나 중복된 폴더와 파일 이름 대소문자를 확인하세요. | | URL 바로 열립니다. 플레이어 가져오기 실패 | 플레이어 페이지 출처를 GET/HEAD CORS에 추가하세요. CDN 응답 헤더를 확인하고 영향을 받은 오래된 캐시 응답을 무효화합니다. | | 다운로드가 성공했습니다. 재생 실패 | 패키지 게시, 매니페스트 경로, MIME 유형 및 DRM 라이선스 인증을 확인하세요. [재생 문제 해결](https://docs.drm-x.com/ko/troubleshooting/playback)을 참조하세요. | **CloudFront 403:** OAC가 요청에 서명하고 버킷 정책이 올바른 배포 ARN 및 접두사를 사용하며 원본이 S3 REST 엔드포인트인지 확인합니다. S3 Block Public Access를 계속 켜두세요. SSE-KMS를 선택한 경우 KMS 권한을 확인하세요. ## 공식 참고자료[#](#references) - [ S3 버킷](https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html) 만들기 - [관리 IAM 액세스 키](https://docs.aws.amazon.com/IAM/latest/UserGuide/access-key-self-managed.html) - [S3 CORS 구성](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ManageCorsUsing.html) - [CloudFront OAC 및 S3 버킷 정책](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html) - [CloudFront 응답 헤더](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-response-headers.html) - [관리형 원본 요청 정책](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html) - [맞춤 도메인 및 인증서](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/add-domain-existing-distribution.html) Cloudflare를 사용하시나요? [Cloudflare R2 설정](https://docs.drm-x.com/ko/storage/cloudflare-r2)을 따르세요.